nodejs 函数promise化
2017-11-29 本文已影响0人
qwerrghj
一. 概念
指将带有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)
})