nodejs promise callbacks区别_[JavaScript] Promise.All的冷思考

9f5a6db97e93b14eee5594f6a0aca30a.png

问题, 什么是 Promise.all ? 可能在做的各位读者都经历了ES6, ES7 语法迭代带来的书写代码的快感了.

实例

var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
  setTimeout(resolve, 100, 'foo');
});

Promise.all([promise1, promise2, promise3]).then(function(values) {
  console.log(values);
});

4c09dcf8a3352a5bd5ed5b7bae28439b.png

这个 arrOfPromises 的最大长度是什么?

const arrOfPromises = [];
Promise.all(arrOfPromises).then(/*    */); 

首先我们要知道 JavaScript 无论在Nodejs, 还是 Browser里面运行. 目前的机制还是单线程(Single Thread). (这边文章不参与WebWorker, ServiceWorker的讨论, 谢谢.)

其次理解: ParallelConcurrent的概念区别

93dc359769e1729acb1d33c6e6ec5116.png

关键点就是这个: 这里的Promise.all, 底层实现还是Concurrent. 所以arrOfPromises里的每个Promise都会占用一定时间.

如果arrOfPromises的长度很大, 比如说 size => 1000, 造成的结果可能就是服务器的timeout . 可以看下这个reddit的node.js 讨论: https://www.reddit.com/r/node/comments/96yt7s/promiseall_with_thousands_of_get_request/

所以这个Concurrency 的 Size肯定是有限制的, 而且在一定是在一个写死的限制内 (hard coded)


如果是在Chrome里面运行的话: 默认是5, 最大是10

1. Home - Browserscope

2. How can I tell Chrome to use all 6 concurrent connections asap? - Webmasters Stack Exchange

如果是在Nodejs 里面运行的话:

跟Chrome本身比较的话, Chrome用的是Application级别分出来的Sockets, 而Nodejs用的是系统的Sockets. 所以nodejs 默认是, 无限大 (Infinity), 当然可以自己设置大小限制.

去Node.js v10.15.3 Documentation 搜索 maxSockets.


结论

既然Promise.all 是有size限制的, 那么我们应该怎么去克服这个问题呢?

哈哈, 这个问题已经被很多的前辈解决了, 那就是用Queue, 把他们分段处理.

代码示例 (async)

import queue from 'async/queue';

// create a queue object with concurrency 2
var q = async.queue(function(task, callback) {
    console.log('hello ' + task.name);
    callback();
}, 2);                            //  2 是亮点, 意思是最多2个同时进行

// assign a callback
q.drain = function() {
    console.log('all items have been processed');
};

// add some items to the queue
q.push({name: 'foo'}, function(err) {
    console.log('finished processing foo');
});
q.push({name: 'bar'}, function (err) {
    console.log('finished processing bar');
});

// add some items to the queue (batch-wise)
q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {
    console.log('finished processing item');
});

Youtube视频示例: Exploring Async.js - async.queue

推荐2个solutions 供各位参考:

  1. async - Documentation
  2. What is the best way to limit concurrency when using ES6's Promise.all()?

更多的优雅写法就需要各位自己去探索了, 欢迎留言点赞转发. 谢谢!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值