美文网首页
nodejs 函数promise化

nodejs 函数promise化

作者: qwerrghj | 来源:发表于2017-11-29 11:37 被阅读0次

    一. 概念

    指将带有callback函数重新变成promise来实现

    二. 使用

    需要引入一个promise库如bluebird,利用其promisify和promisifyall方法

    1. promisify方法

    需要nodeCallback(错误优先的回调)回调函数转为promise (nodejs标准包的异步回调几乎是nodeCallback)

    var Promise = require('bluebird')
    var fs = require('fs')
    
    // 异步回调形式
    fs.readFile('./test.js',function(err, data){
        console.log(data)
    })
    
    // promisify 形式
    const readFileAsync = Promise.promisify(fs.readFile)
    
    readFileAsync('./test.js').then(function(data){
        console.log(data)
    }).catch(e){
        console.log(e)
    }
    

    2. promisifyall方法

    将一个库的所有方法全部转化为promise实现,并将原有函数名加上Async

    var Promise = require('bluebird')
    
    // promisifyall 形式
    const fs = Promise.promisifyall(require('fs'))
    
    fs.readFileAsync('./test.js').then(function(data){
        console.log(data)
    }).catch(e){
        console.log(e)
    }
    

    三. 实现自己的promisify

    1. 单一函数就是promise封装

    // 如对fs的异步读取文件函数封装promise
    // 返回一个promise 同时针对回调的不同参数返回不同的处理结果,方便之后调用
    
    var promisify = function(fpath, encoding){
        return new Promise(function(resolve, reject){
            fs.readFile(fpath, encoding, function(err, result){
                if(err) return reject(err)
                else return resolve(result)
            })
        })
    }
    

    2. 函数一般化

    将需要转化的函数当成一个方法传入,因为不同函数接受的参数不同,需要用到methods.apply()

    var promisify = function (method, ctx) {
        return function () {
            // 获取method调用的需要参数
            var args = Array.prototype.slice.call(arguments, 0);
                    
            // use runtime this if ctx not provided
            ctx = ctx || this;
    
            //返回一个新的Promise对象
            return new Promise(function (resolve, reject) {
                // 除了函数传入的参数以外还需要一个callback函数来供异步方法调用
                var callback = function () {
                    return function (err, result) {
                        if (err) {
                            return reject(err);
                        }
                        return resolve(result);
                    };
                }
                args.push(callback());
                // 调用method
                method.apply(ctx, args);
            });
        };
    };
    
    // 调用
    var readFileAsync = promisify(fs.readFile)
    readFileAsync('./test.txt', 'utf8').then(function(data){ 
      console.log(data) 
    })
    

    相关文章

      网友评论

          本文标题:nodejs 函数promise化

          本文链接:https://www.haomeiwen.com/subject/rwdubxtx.html