node 模块 howdo 异步流程控制

发布于 2021-12-02 12:41:41 字数 4561 浏览 1056 评论 0

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
427 人气
更多

推荐作者

6118422078

文章 0 评论 0

Bonjour°[大白

文章 0 评论 0

別甾虛僞

文章 0 评论 0

qq_FynBW0

文章 0 评论 0

浅笑依然

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文