node 模块 howdo 异步流程控制
1、生活例子
例1:我一边听歌,一边阅读10次课文。在我们的大脑里,现在已经分配了11个并行任务(一起做):
- 任务1:听歌。
- 任务2-11:阅读10次课文。
这11个任务是可以同时进行的。
例2:我打开书本,然后阅读10次课文。在我们的大脑里,现在已经分配了11个串行任务(跟着做):
- 任务1:打开书本。
- 任务2:在打开书本之后,阅读 10 次课文。
在现实生活中,我们不能处理大量的并行和串行任务,我们需要手动将我们的任务肢解开来,比如从早上到晚上这一天的时间,我们需要做很多事情。我们需要在大脑里将任务按照某种顺序分解开来。比如上午看书,下午打球,这两件事是跟着做的,只有看完书之后才可以打球。然后上午先看语文,然后看数学,这也是一个串行任务(跟着做)。下午一边打球,一边和朋友聊天,这两件事是并行的,是一起做的。
计算机的事情,需要我们人为去分配任务,我们可以参考我们的现实生活,把需要做的事情,按照并行和串行分开,简化分配任务,然后小任务合成大任务。这样,一件复杂的事情也可以按照分配情况预期完成。
2、howdo 的 API
howdo
的思想和上面说的生活例子是一样的道理,把任务按照执行类型(一起做的还是跟着做的)分类开来,然后再去分配任务。howdo
的API非常的简洁,只有 #task
、#each
、#follow
和 #together
四个,而且使用非常简单,可以链式混合使用,其中 #follow
和 #together
是链式终点。
2.1、#task 分配单次任务
分配单次任务是一个计划过程,就是在任务执行之前约定好怎么做。
var howdo = require('howdo');
howdo
// 单次任务1
.task(funtion(next) {
next(null, 1, 2);
})
// 单次任务2
.task(funtion(next, ret1, ret2) {
// ret1 = 1
// ret2 = 2
next(null, ret1 + ret2);
})
// 跟着做
.follow(function(err, ret3){
// ret3 = 3
});
howdo
// 单次任务1
.task(funtion(done) {
done(null, 1, 2);
})
// 单次任务2
.task(funtion(done) {
done(null, 3);
})
// 一起做
.together(function(err, ret1, ret2, ret3) {
// ret1 = 1
// ret2 = 2
// ret3 = 3
});
#task
是可以链式操作的,每当开始执行task都会实例化一次新的任务计划。如果链式不得不断开的话,请先缓存起来。
2.1、#each 分配批量任务
分配批量任务也是一个计划过程,就是在任务执行之前约定好怎么做。
var howdo = require('howdo');
howdo
// 批量任务1
.each([1, 2, 3], funtion(key, val, next) {
next(err, val);
})
// 批量任务2
.each({
a: 4,
b: 5,
c: 6,
}, funtion(key, val, next, ret1) {
next(err, ret1 + val);
})
// 跟着做
.follow(function(err, ret) {
// ret = 18 = 3 + 4 + 5 + 6
});
howdo
// 批量任务1
.each([1, 2, 3], funtion(key, val, done) {
done(err, val);
})
// 批量任务2
.each({
a: 4,
b: 5,
c: 6,
}, funtion(key, val, done) {
done(err, val);
})
// 一起做
.together(function(err, ret1, ret2, ret3, ret4, ret5, ret6) {
// ret1 = 1
// ret2 = 2
// ret3 = 3
// ret4 = 4
// ret5 = 5
// ret6 = 6
});
#each
也是链式操作的,可以与 #task
合起来用。
2.3、#follow 跟着做
任务分配好后,任务跟着做,只回调最后一次结果。
2.4、#together 一起做
任务分配好后,任务一起做,回调任务顺序的所有结果。
3、howdo的一些注意点
3.1、next 参数
和 nodejs 的约定一样,next是回调函数,第1个参数始终为 error 对象,为空表示无错误,不为空时该参数必须为 Error 对象的实例。next 意思是把当前任务结果传递给下一个任务。格式为:
howdo.task(function(next) {
next(err, ret1, ret2, ret3, ...);
});
3.2、done 参数
与 next 参数格式一致。它的使用场合是,把当前任务结果提交给总结。例如,大家把作业都统一交给班长,这个交作业的过程为 done。格式为:
howdo.task(function(done) {
done(err, ret1, ret2, ret3, ...);
});
如果 done
的结果非常的多,那么在最后所有结果合并的时候,可能造成识别困难,因此推荐每一个任务只提交1个结果:
howdo.task(function(done) {
done(err, ret);
});
3.3、each 参数
each
是和 task
同级的,不同的作用是,each
可以一次性定义批量任务。这些批量任务是可以并行也可以是串行的,非常的实用。each
使用比较复杂,参数也非常的多,参数有:
howdo.each(object, function(key, val, next, prevRet1, prevRet2) {
next(err, ret1, ret2, ret3, ...);
});
howdo.each(object, function(key, val, done) {
done(err, ret1, ret2, ret3, ...);
});
- 参数1:是需要 each
的对象,可以是数组和对象
- 参数2:是一个回调函数
- 参数1:键
- 参数2:值
- 参数3:可以是 next
或者 done
剩余参数:如果是 follow
的话,那么剩下的参数为上一次传递下来的结果
3.4、follow 参数
follow
是链式终点,它也是回调函数,因此第一个参数为错误标记,剩余参数为最后一次任务的结果。
.follow(function(err, ret1, ret2, ret3) {
// ret1 = 4
// ret2 = 5
// ret3 = 6
});
如第1次任务结果为 1,第2次任务结果为 2、3,最后第3次任务结果为 __4、5、6__,那么 __ret1、ret2、ret3 分别为 4、5 和 6__。
3.5、together 参数
together
也是链式终点,它也是回调函数,因此第一个参数为错误标记,剩余参数为所有任务的结果集合。
.totether(function(err, ret1, ret2, ret3, ret4, ret5, ret6) {
// ret1 = 1
// ret2 = 2
// ret3 = 3
// ret4 = 4
// ret5 = 5
// ret6 = 6
});
如第1次任务结果为 1,第 2 次任务结果为 2、3,最后第 3 次任务结果为 __4、5、6__,那么 __ret1、ret2、ret3、ret4、ret5、ret6 分别为 1、2、3、4、5 和 6__。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 使用 Nginx 静态网站配置
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论