一. 概念
指將帶有callback函數(shù)重新變成promise來(lái)實(shí)現(xiàn)
二. 使用
需要引入一個(gè)promise庫(kù)如bluebird,利用其promisify和promisifyall方法
1. promisify方法
需要nodeCallback(錯(cuò)誤優(yōu)先的回調(diào))回調(diào)函數(shù)轉(zhuǎn)為promise (nodejs標(biāo)準(zhǔn)包的異步回調(diào)幾乎是nodeCallback)
var Promise = require('bluebird')
var fs = require('fs')
// 異步回調(diào)形式
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方法
將一個(gè)庫(kù)的所有方法全部轉(zhuǎn)化為promise實(shí)現(xiàn),并將原有函數(shù)名加上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)
}
三. 實(shí)現(xiàn)自己的promisify
1. 單一函數(shù)就是promise封裝
// 如對(duì)fs的異步讀取文件函數(shù)封裝promise
// 返回一個(gè)promise 同時(shí)針對(duì)回調(diào)的不同參數(shù)返回不同的處理結(jié)果,方便之后調(diào)用
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. 函數(shù)一般化
將需要轉(zhuǎn)化的函數(shù)當(dāng)成一個(gè)方法傳入缩擂,因?yàn)椴煌瘮?shù)接受的參數(shù)不同,需要用到methods.apply()
var promisify = function (method, ctx) {
return function () {
// 獲取method調(diào)用的需要參數(shù)
var args = Array.prototype.slice.call(arguments, 0);
// use runtime this if ctx not provided
ctx = ctx || this;
//返回一個(gè)新的Promise對(duì)象
return new Promise(function (resolve, reject) {
// 除了函數(shù)傳入的參數(shù)以外還需要一個(gè)callback函數(shù)來(lái)供異步方法調(diào)用
var callback = function () {
return function (err, result) {
if (err) {
return reject(err);
}
return resolve(result);
};
}
args.push(callback());
// 調(diào)用method
method.apply(ctx, args);
});
};
};
// 調(diào)用
var readFileAsync = promisify(fs.readFile)
readFileAsync('./test.txt', 'utf8').then(function(data){
console.log(data)
})