bluebird之Promisify原理

文档 www.npmjs.com/package/blu…
安装 npm install bluehird

Promisify

简单用法

let fs = require('fs');
let bluebird = require('bluebird');
let read = bluebird.promisify(fs.readFile);

read('1.txt','utf-8').then(function(data){
    console.log(data);
})
复制代码

上例,用bluebird的promisify方法,将fs中的readFile方法promise化,也就是说,read方法执行后,会返回一个promise,可以调用then方法执行成功的回调或失败的回调

promisify就是在将readFile包装成一个promise,并处理了readFile的回调方法,下面这段代码可以帮助理解它是怎么做到的

一个promisify的实现
function promisify(fn) { 
    return function (...args) {
        return new Promise(function (resolve, reject) {
            fn(...args, function (err, data) {
                if (err) reject(err);
                resolve(data);
            })
        })
    }
}
复制代码

promisify化后,案例中read即为return的函数,当read执行时,new了一个promise,同时fn也会执行,这里也就是readFile方法会执行,readFile的参数即read调用时传进来的参数,readFile成功时,调用promise的resolve,失败时调用reject,这样就将readFile包装成了一个promise

PromisifyAll

promisifyAll(fs); //就是将fs中所有的方法全部增加一个promise化的方法

promisifyAll的简单实现
function promisifyAll(obj) {
    Object.keys(obj).forEach(key => { // es5将对象转化成数组的方法
        if (typeof obj[key] === 'function') {
            obj[key + 'Async'] = promisify(obj[key])
        }
    })
}
复制代码

将fs库中所有的方法名都加上Async后缀
比如readFile,会增加一个readFileAsync的方法,这个方法就是promisify化的readFile

第一个用法也可以写为

let fs = require('fs');
promisifyAll(fs); //或用bluebird提供的promisifyAll接口
fs.readFileAsync('1.txt', 'utf8').then(function (data) {
    console.log(data);
});
复制代码

那么实际应用中,一个方法满足这几个条件,可以被promisify化

  • 该方法必须包含回调函数
  • 回调函数必须执行
  • 回到函数第一个参数代表err信息,第二个参数代表成功返回的结果

当A、B、C、D四个异步执行方法,B的执行依赖A的执行结果,C的执行依赖B的执行结果,那我们之前会用A嵌套B,B嵌套C,C嵌套D的写法
现在可以将每个异步方法promisify化为promiseA、promiseB、promiseC、promiseD,最后通过promise链式调用,确保顺序执行

promiseA()
.then(promiseB)
.then(promiseC)
.then(promiseD)
.catch(function(err){
    console.log(err);
});
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值