回调形式的流程控制 async库的使用
一个关于node流程控制的问题,喜欢写回调模式的可以看过来 async包括 顺序执行(series),瀑布流执行(waterfall),并行执行(parallel)(parallelLimit)这几个应该是常用的 直接上代码了,本人用的是async库
var async = require('async');
async.series([
function(cb){
setTimeout(function(){
cb(null, 1);
}, 1000);
},
function(cb){
setTimeout(function(){
cb(null, 2);
}, 1000);
}
], function(error, result){
if(error){
console.log(error);return;
}
console.log('parallel:消耗时间为数组的每个方法执行时间的总合, result的结果为每个方法的返回结果,和数组顺序对应');
console.log('parallel:',result);
});
/*并行执行*/
async.parallel([
function(cb){
setTimeout(function(){
cb(null, 1);
}, 1000);
},
function(cb){
setTimeout(function(){
var c = 1 + 100;
cb(null, c);
}, 1000);
}
], function(error, result){
if(error){
console.log(error);return;
}
console.log('parallel:消耗时间为数组中的执行最长的一个方法, result的结果为每个方法的返回结果,和数组顺序对应');
console.log('parallel:', result);
});
/*paramllelLimit参数是三个,第二个则为限制并行的数量*/
async.parallelLimit([
function(cb){
setTimeout(function(){
cb(null, 1);
}, 1000);
},
function(cb){
setTimeout(function(){
var c = 1 + 100;
cb(null, c);
}, 1000);
}
], 1, function(error, result){
if(error){
console.log(error);return;
}
console.log('parallelLimit:消耗时间为数组中的执行最长的一个方法, result的结果为每个方法的返回结果,和数组顺序对应');
console.log('parallelLimit:', result);
});
11 回复
promise之前async是首选,个人也挺喜欢这个库
login(user, pass, function(result) {
doSomeThing(result, function(err) {
switch(err) {
case 'disconnect':
goto login;
case 'retry':
goto doSomeThing;
default:
logout(function() {
console.log('finish');
}
}
}
}
就这个例子,怎么用async或promise?
loginAync(user, pass).then(function(result){
return doSomeThing(result)
}).then(function(err){
}).catch(function(err){
})
要实现那句 goto doSomeThing 的逻辑,怎么办呀?
async.series([user, pass], function(error, result){
doSomeThine(result, function(err){
});
});
这样也可以吧
问的是 那两个goto逻辑 怎么实现?
promise大法好,generator大法好
可以运行验证,大法也就那么回事。
var Steps = require("promise-tiny/Steps");
new Steps({
user: 'foo',
pass: 'foolish',
loginCount: 0,
doSomeThingCount: 0
}) .on('Begin', function(next) { // 从这里开始
next('login', [this.user, this.pass]);
})
.on('login', function(next, user, pass) {
console.log('login("'+user+'", "'+pass+'")');
this.loginCount++;
var result = true; // 假设login总能成功
console.log(' 第'+this.loginCount+'次login成功');
console.log();
next('doSomeThing', '一些要做的事情...');
})
.on('doSomeThing', function(next, ...args) {
console.log('doSomeThing("'+args+'")');
this.doSomeThingCount++;
if(this.doSomeThingCount === 1) { // 假设第一次做不成功,重试一次
console.log(' 第'+this.doSomeThingCount+'次doSomeThing失败,再试一次');
next('doSomeThing', args);
}
else if(this.loginCount === 1) { // 假设第二次做不成功,重新login
console.log(' 第'+this.doSomeThingCount+'次doSomeThing失败,重新login');
next('login', [this.user, this.pass]);
}
else {
console.log(' 第'+this.doSomeThingCount+'次doSomeThing完成了,要退出了');
next('logout');
}
console.log();
})
.on('logout', function(next) {
console.log('logout()');
})
运行结果
login("foo", "foolish")
第1次login成功
doSomeThing("一些要做的事情...")
第1次doSomeThing失败,再试一次
doSomeThing("一些要做的事情...")
第2次doSomeThing失败,重新login
login("foo", "foolish")
第2次login成功
doSomeThing("一些要做的事情...")
第3次doSomeThing完成了,要退出了
logout()
@gzhangzy 用Promise写的:
var loginCount = 0;
var doSomeThingCount = 0;
var login = function () {
return new Promise(function (resolve, reject) {
loginCount++;
console.log('login: %d', loginCount);
resolve(doSomeThing());
});
};
var logout = function () {
return new Promise(function (resolve, reject) {
console.log('logout');
resolve('logout');
});
};
var doSomeThing = function () {
return new Promise(function (resolve, reject) {
doSomeThingCount++;
console.log('doSomeThing: %d', doSomeThingCount);
if (doSomeThingCount === 1) {
resolve(doSomeThing());
} else if (loginCount === 1) {
resolve(login());
} else {
resolve(logout());
}
});
};
login().then(function (result) {
console.log('done');
}).catch(function (err) {
console.error('error: %j', err);
});
输出:
login: 1
doSomeThing: 1
doSomeThing: 2
login: 2
doSomeThing: 3
logout
done
写的不错!
@gzhangzy 多谢多谢,个人爱好写回调