Node.js 异步流程控制
来源:互联网 发布:淘宝老店新开流量限制 编辑:程序博客网 时间:2024/05/17 09:21
Node.js 异步流程控制
异步流程控制对象async
- 串行无关联:async.series
- 并行无关联:async.parallel
- 串行有关联:waterfall
- parallelLimit:parallelLimit函数和parallel类似,但是他多了一个参数limit
- limit参数限制任务只能同时并发一定数量,而不是无限制并发
首先我们需要安装async模块:
我们来看看同步的情况:
function oneFun(){ console.log("oneFun");}function twoFun(){ console.log("twoFun");}oneFun();twoFun();console.log("end");
方法同步执行。
现在我们来写一个异步的例子:
function oneFun(){ var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); } },1000);//每隔1秒调用一次}function twoFun(){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); } },1000);//每隔1秒调用一次}oneFun();twoFun();console.log("end");
我们发现两个方法交叉执行。
如果我们想要oneFun执行完在执行twoFun的话,我们需要如下改写代码:
function oneFun(){ var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); twoFun();//等待oneFun执行完回调 } },1000);//每隔1秒调用一次}function twoFun(){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); } },1000);//每隔1秒调用一次}oneFun();console.log("end");
我们发现实现了我们想要的,但是如果我们要执行的方法很多,就需要回调中继续嵌套回调,这样看起来很乱而且难以维护。
async.series
我们接下来用async.series来改造:
var async = require('async');function exec(){//串行无关联 async.series( { //这里面是串行的方法 one : function(done){ //回调函数写在这 done(null,'one完毕');//done执行完之后才会执行two函数 }, two : function(done){ done(null,'two完毕'); } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
var async = require('async');function exec(){//串行无关联 async.series( { //这里面是串行的方法 one : function(done){ //回调函数写在这 done('错误','one完毕');//只要done不执行就不会执行下一个函数 }, two : function(done){ done(null,'two完毕'); } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
所以出现错误之后,下一个函数two就不执行了。
var async = require('async');function exec(){//串行无关联 async.series( { //这里面是串行的方法 one : function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done(null,'one完毕'); } },1000);//每隔1秒调用一次 }, two : function(done){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); done(null,'two完毕'); } },1000);//每隔1秒调用一次 } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
我们可以看出oneFun执行完毕之后,two才开始执行
- series可以接受数组作为参数,需要串行处理的方法作为数组的元素。
var async = require('async');async.series( [ function (callback) { setTimeout(function () { console.log('event A occurs') callback(null, 'A') // 第一个参数是异常错误,第二个参数是返回值 }, 3000) }, function (callback) { console.log('event B occurs'); callback(null, 'B') } ], function (err, results) { // results是返回值的数组 console.log('event ' + results[0] + results[1] + ' occurs') })console.log("event D occurs")
- async.series也可以接受对象作为参数,代码如下:
var async = require('async');async.series( { A: function (callback) { setTimeout(function () { console.log('event A occurs') callback(null, 'A') // 第一个参数是异常错误,第二个参数是返回值 }, 3000) }, B: function (callback) { console.log('event B occurs'); callback(null, 'B') } }, function (err, results) { // results是所有的返回值合集,results.A获取的是A的返回值。 console.log('event ' + results.A + results.B + ' occurs') })console.log("event D occurs")
var async = require('async');function exec(){//串行无关联 async.series( { //这里面是串行的方法 one : function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done('错误','one完毕'); } },1000);//每隔1秒调用一次 }, two : function(done){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); done(null,'two完毕'); } },1000);//每隔1秒调用一次 } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
oneFun的done出现错误,所以被拦截了,所以twoFun就不会执行。
注意:如果任何一个方法在callback中返回了一个异常错误,停止后续方法的执行,且async.series的回调立即执行。
async.parallel
- async.parallel可以接受对象作为参数
var async = require('async');function exec(){//并行无关联 async.parallel( { one : function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done(null,'one完毕'); } },1000);//每隔1秒调用一次 }, two : function(done){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); done(null,'two完毕'); } },1000);//每隔1秒调用一次 } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
- async.parallel可以接受数组作为参数
var async = require('async');async.parallel( [ function (callback) { setTimeout(function () { console.log('event A occurs') callback(null, 'A') }, 3000) }, function (callback) { console.log('event B occurs') callback(null, 'B') } ], function (err, result) { console.log("event C occurs") console.log(result) })console.log("event D occurs")
var async = require('async');function exec(){//并行无关联 async.parallel( { one : function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done('错误','one完毕'); } },1000);//每隔1秒调用一次 }, two : function(done){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); done(null,'two完毕'); } },1000);//每隔1秒调用一次 } },function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
注意:
1、并行执行,所有任务执行完后,立即执行回调函数。
2、如果有一个任务执行异常报错,立即执行回调函数。
async.waterfall
waterfall:串行,前一个任务的结果传递给后一个任务。
var async = require('async');function exec(){ async.waterfall( [ function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done(null,'one完毕'); // 第一个参数是error,第二个参数是下一个任务的参数 } },1000);//每隔1秒调用一次 }, function(preValue,done){ var j = 0; setInterval(function(){ console.log("twoFun"); j++; if(j == 3){ clearInterval(this); done(null,preValue + ',two完毕'); } },1000);//每隔1秒调用一次 } ],function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
var async = require('async');function exec(){ async.waterfall( [ function(done){ //回调函数写在这 var i = 0; /* setTimeout(function(){ console.log("oneFun"); },1000);//1秒之后调用 */ setInterval(function(){ console.log("oneFun"); i++; if(i == 3){ clearInterval(this); done(null,'one完毕'); } },1000);//每隔1秒调用一次 }, function(preValue,done){ var j = 0; setInterval(function(){ console.log(preValue + "twoFun"); j++; if(j == 3){ clearInterval(this); done(null,preValue + ',two完毕'); } },1000);//每隔1秒调用一次 } ],function(err,rs){ console.log(err); console.log(rs); } )}exec();console.log("end");
阅读全文
0 0
- Node.js 异步流程控制
- Node.js系列--异步流程控制
- 关于node.js中的异步流程控制
- node.js 异步流程控制async
- node异步流程控制
- node js 异步执行流程控制模块Async介绍
- Node js 异步执行流程控制模块Async compose
- 【深入浅出Node.js系列十四】Nodejs异步流程控制Async
- node js 异步执行流程控制模块Async介绍
- node js 异步执行流程控制模块Async介绍
- Node.js项目--流程控制器、控制异步回调利器
- node.js promise 流程控制
- node异步编程流程控制库
- node.js 中的流程控制一
- node.js 中的流程控制二
- 用 Generator 实现 JS 异步流程控制
- 异步流程控制(js前端)
- node.js的几种异步控制的方法
- Vulkan规范:第七章 7
- C++命名空间详解
- Ubuntu16.04搭建以太坊开发环境
- Object.wait notify notifyAll native
- const关键字修饰指针速记的好方法
- Node.js 异步流程控制
- Mac下安装、配置Go语言开发环境
- The supplied data appears to be in the Office 2007+ XML
- LoadRunner压力测试:详细操作流程
- Vulkan规范:第七章 7.1
- 与李老师的谈话
- Vulkan规范:第七章 7.2 ~ 7.3
- JavaScript 学习笔记 (3)
- NULL