series 循环_源码级分析waterfull,parallel,series方法

本文深入分析了async.js库中的waterfall, parallel, series这三个异步方法,从源码层面解释了它们如何保证函数执行、创建迭代器、控制并发,并详细比较了三者之间的差异。waterfall保证逐个执行并传递结果,parallel并发执行,series顺序执行但不传递结果。" 122976662,10771759,Java定时任务:清晨8点自动发送通知,"['Java', '后端开发', '定时任务', '数据库操作', '服务接口']
摘要由CSDN通过智能技术生成

说明

以下内容全部来自对async.js的源码分析,在日常工作中遇到最多的几个方法就是waterfull,parallel,series。所以,本文主要对该三个方法进行详细的分析,后续如有真实的使用场景也能做到得心应手。废话不多说,直接上代码:

1.如何保证函数只会被执行一次

ca807af9116e69ec093ef9e7cb7ba652.png

而下面的onlyOnce在被第二次调用的时候直接抛出错误:

7f98cf6af06b019f31d35c4b1e673466.png

2.如何创建一个迭代器对象

8ab17f23bba28179fb47c49968acfc6b.png

3.如何控制并发的数量

61f497b81f830a42f9cc04e74e0cd89a.png

上面之所以重点讲解了:只会执行一次的函数,迭代器对象,控制并发数量的方式,是因为后面章节中会被反复使用。所以读到此处,建议对上面的内容好好咀嚼下!

4.waterfull vs parallel vs series异步方法详解

4.1 如何将同步函数包装为异步

顾名思义,asyncify就是将我们的常规的函数包装为异步的,接受参数加回调的方式,与nodejs中所有内部函数的签名保持一致。有了上面的工具函数源码解析,下面看看asyncify方法内部的具体逻辑:

bc7f65c381f47df0c7c63f9f017c8d1b.png

有了对内部处理逻辑的分析,下面看看具体代码如何调用:

ea2687607a4841c71b78e02a362be7e0.png

这个asyncify函数接受一个同步函数,将它转化为异步的,同时将asyncify包裹的函数的返回值传递给回调函数callback。这个方法常用于:waterfall/series或者其他异步的函数。为asyncify返回的函数传递的任何参数会被传递给包裹的函数,但是不包括最后一个回调函数(initialParams中的args.pop调用后args已经改变了)。如果有错误抛出,那么也会被传入到callback回调。

如果传入asyncify函数的返回值是Promise,那么这个Promise的resolve ,reject状态会被传入到回调callback回调中。这也就是说你可以为asyncify传入async函数!

4.2 asyncify用于waterfull

下面是waterfall给出的完整的代码:

b3e2a376179cacd23c7498604d944dfb.png

其中为每一个tasks中的函数都进行了asyncify处理,使得这个函数的签名为(...args,callback)。同时,因为asyncify处理的时候,会将包裹的函数的真实调用结果传递给callback回调,同时第一个参数为error。

下面是waterfall具体的调用代码实例:

09079ecd490f279729acd943eeba982f.png

也可以使用下面的方式来调用:

ce567377bd414a6e1ca91d87b2f5f767.png

waterfull方法,顾名思义:就是在Collection中的前一个asyncify的函数执行完毕后,再将结果传递给下一个asyncify的函数,当所有的函数都执行完毕后,调用我们的callback回调。

4.3 asyncify用于parallel方法

上面的"如何控制并发的数量"部分已经说过如何控制并发遍历(eachOfLimt.js)。下面再讲一个用于不对并发量进行限制的方法(eachOf.js)。该方法可以用于对象和数组:

00907f15376564be9480f0e8d11eb92a.png

上面的eachOf方法可以看出,每一个回调中并没有在callback中传入value,只是循环调用集合中的方法而已。下面是parallel的代码:

a96fd6e8d3f2e7ba3f63732894939314.png

该方法的真实用法如下:

ba12620bd0d6d5b061f501b4eeef874a.png

注意:我们parallel回调函数的值也是按顺序的,即第一个回调函数的值,第二个回调函数的值....。parallel和waterfull的区别在于:parallel不会控制并发量,而waterfall必须等前一个函数执行结束后才会执行下一个方法,同时也会将前一个方法的值传递给后一个方法而parallel因为是并发执行的,所以只能获取到最终的结果而不能获取到前一个函数的执行结果

4.3 asyncify用于series

7f8abbc75f8dfd602a0ce9f3d161c4f2.png

看看eachOfSeries.js方法的代码:

f4231b6cb5cf7a72e31fbf4524941064.png

也就是series通过eachOfLimit.js将并发量控制为1。同时从series.js可以看到,它也使用了上面的parallel.js,所以它的返回值只可能是和parallel一样的类型,即results[key] = result类型。也就是说,虽然series方法可以保证代码按顺序执行,即前一个函数执行完毕才执行后面的函数(和parallel的主要区别),但是只有在回调函数中可以获取到所有函数的结果,而不能获取前一个函数的调用结果。下面是具体的例子:

55b7aaa962f2667827499ed1242c8b27.png

或者可以采用下面的方式:

37303015f15ee3457d152ba5753d2bb4.png

5.waterfull vs parallel vs series方法总结

从上面的分析知道,控制并发量其实就是控制了同一个时间最多执行的函数个数,其主要是通过eachOfLimit.js实现的。到这里,我想大家对于三个方法的区别和能力已经有了比较深入的了解了吧。我们下期再见吧

554446aeaa8ad0ec3c01c9633433bde8.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值