node.js promise 流程控制

promise 一个标准,Promise也已经纳入了ES6,而且高版本的chrome、firefox浏览器都已经原生实现了Promise,它描述了异步调用的返回结果,包括正确返回结果和错误处理,可以解耦异步调用中的复杂嵌套问题。关于详细的说明文档可以参考 Promises/A+ 。目前实现 promise 标准的模块有很多,如 Q 、 bluebird 和 Deferred ,下面我们以 Q 为例,介绍一下 promise 在 nodejs 中的使用方法。

有这么一个场景:有三个文件file1、file2、file3,按照先后顺序依次读取,然后拼接起来(或者说一个函数用到另外一个函数的值)。

传统通过回调嵌套方式实现同步,来保障拼接的字符串不会乱。

var str = 'begin';fs.readFile('file1.txt', function(err, data1) {str += data1;fs.readFile('file2.txt', function(err, data2) {str += data2;fs.readFile('file3.txt', function(err, data3) {str += data3;});});});我们现在采用基于promise规范的Q

安装:npm install q

引入项目:var Q = require(‘q’);

首先将上面3层嵌套代码解耦和,并用Q.deferred构建

var Q = require('q'),fs = require('fs');var str = 'begin';function read1(data) {var deferred = Q.defer();fs.readFile('file1.txt', function(err, data1) {if (err) {deferred.reject(err);} else {deferred.resolve(data += '~' + data1);}});return deferred.promise;}function read2(data) {var deferred = Q.defer();fs.readFile('file2.txt', function(err, data2) {if (err) {deferred.reject(err);} else {deferred.resolve(data += '~' + data2);}});return deferred.promise;}function read3(data) {var deferred = Q.defer();fs.readFile('file3.txt', function(err, data3) {if (err) {deferred.reject(err);} else {deferred.resolve(data += '~' + data3);}});return deferred.promise;}then

链式用q的then串联,链式实现了函数值依次传递。

read1('begin').then(read2).then(read3).done(function(data) {}, function(err) {});Q.all

Q.all可以传入数组,数组含有n个函数,数组内的函数是异步执行的,spread收集每个函数的返回值

Q.all([read1(),read2(),read3()]).spread(function(data1, data2, data3) {console.log(data1, data2, data3);});或者Q.spread([read1(),read2(),read3()]).spread(function(data1, data2, data3) {console.log(data1, data2, data3);});Q.allSettled

函数数组方式,当函数中出现err(deferred.reject)或者没有返回deferred.resolve,done、spread不会返回值。Q.allSettled是用于保障函数出现异常时候,不会中断其它函数运行,最后统一返回值。

我们测试一下,让read1只返回deferred.reject

function read1(data) {var deferred = Q.defer();fs.readFile('file1.txt', function(err, data1) {// if (err) {deferred.reject(err);// } else {// deferred.resolve(data += '~' + data1);// }});return deferred.promise;}执行Q.allSettled([    read1(),    read2(),    read3()]).spread(function(data1, data2, data3) {    console.log(data1, data2, data3);});或者Q.allSettled([    read1(),    read2(),    read3()]).then(function (results) {    results.forEach(function (result) {        if (result.state === "fulfilled") {            var value = result.value;        } else {            var reason = result.reason;        }    });});结果{ state: 'rejected', reason: null } { state: 'fulfilled', value: 'undefined~love' } { state: 'fulfilled', value: 'undefined~you' }state: ‘rejected’ 标识运行出现错误;state:’fulfilled’ 完成;reason:null 打印err内容;value:’xxx’ 返回值动态同步函数

如果你有一组函数并且需要顺序执行,可以通过手动的then方式

read1.then(read2).then(read3));也可以动态方式执行函数var funcs = [read1, read2, read3];var result = Q('begin');//定义一个初始值beginfuncs.forEach(function(f) {result = result.then(f);//遍历传参});更简单的方式var funcs = [read1, read2, read3];funcs.reduce(function(soFar, f) {return soFar.then(f);}, Q('begin'));错误处理

使用fail函数

Q.allSettled([read1(),read2(),read3()]).fail(function(error) {});process

Promise有个then方法,then方法可以接受3个函数作为参数。前两个函数对应Promise的两种状态的回调函数fulfiled和rejected,第三个函数用于处理进度信息。

uploadFile().then(function () {// Success uploading the file}, function (err) {// There was an error, and we get the reason for error}, function (progress) {// We get notified of the upload's progress as it is executed});更简单的显示进度方法uploadFile().progress(function (progress) {// We get notified of the upload's progress});结束

结束部分引用了:的内容,如下

三亚呀——赴一个蓝天碧海。

node.js promise 流程控制

相关文章:

你感兴趣的文章:

标签云: