promise
promise
一个标准,它描述了异步调用的返回结果,包括正确返回结果和错误处理。关于详细的说明文档能够参考Promises/A+。目前实现promise
标准的模块有不少,如Q、bluebird和Deferred,下面咱们以Q为例,介绍一下promise
在 nodejs
中的使用方法。node
###将通常的异步调用的函数转换为promise
风格的函数 好比通常状况下,咱们异步读取文件会写出下面的代码:git
fs.readFile("test.txt",function(err,data){ if(!err){ console.log(data); }else{ console.error(err); } });
咱们能够把fs.readFile
函数封装为promise
风格的函数,以下:github
var preadFile = function(file){ fs.readFile(file,function(err,data){ var deferred = Q.defer(); if(!err){ deferred.resolve(data); }else{ deferred.reject(err); } return deferred.promise; }); }
这样咱们就能够这样调用这个方法了:promise
//then 的第一个参数是正确处理函数,第二个参数是错误处理函数 preadFile("test.txt").then(console.log,console.error);
能够看到这样调用更加直接明了。异步
###使用方法函数
各个回调函数顺序传递数据: 在nodejs
中咱们回去数据时,时常遇回调函数的返回结果须要传递给下一个回调函数,到时很大的回调函数嵌套,promise
能够很轻松的在回调函数之间传递参数,看下面的例子:ui
var fun1 = function (data,cb) { cb(null,data+" fun1"); } var fun2 = function (data,cb) { cb(null,data+" fun2"); } var fun3 = function (data,cb) { cb(null,data+" fun3"); } function main(data,cb){ fun1(data,function(err,data){ if(!err){ fun2(data,function(err,data){ if(!err){ fun3(data,cb); }else{ cb(err); } }); }else{ cb(err); } }); }
能够看到main
函数为了获得数据,须要嵌套调用fun1
,fun2
和fun3
,若是须要调用不少函数,那么会造成很大的回调函数嵌套调用,致使代码看起来很丑陋,并且不容易维护,下面咱们改用promise
重写这段代码:code
var Q = require("q"); var fun1 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun1"); return deferred.promise; } var fun2 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun2"); return deferred.promise; } var fun3 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun3"); return deferred.promise; } function main(data,cb){ fun1("test") .then(fun2) .then(fun3) .done(function(data){ cb(null,data);//ok 得到的最终数据为 --->"test fun1 fun2 fun3" },function(err){ cb(err);//failed }); }
收集各个回调函数产生的数据:有时候咱们须要执行不少回调函数,然手把这个回调函数的数据一齐传递给一个函数处理,此时咱们能够使用all
和spread
方法,参看以下代码:文档
var Q = require("q"); var fun1 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun1"); return deferred.promise; } var fun2 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun2"); return deferred.promise; } var fun3 = function (data) { var deferred = Q.defer(); deferred.resolve(data+" fun3"); return deferred.promise; } Q.all([ fun2("test1"),fun3("test2"),fun4("test3") ]).spread(function(){ console.log(arguments);//得到的参数为('test1 fun1', 'test2 fun2', 'test3 fun3' ) });
统一处理错误:传统的回调函数方式使用的话,咱们须要在每个回调函数里判断是否有错误须要处理,这样会存在不少冗余代码,使用promise
的话,能够使用done
或者fail
统一在一个函数中处理错误,如第一个例子同样,使用done
方法的第二个参数处理错误。get