![9f5a6db97e93b14eee5594f6a0aca30a.png](https://i-blog.csdnimg.cn/blog_migrate/7e08b017fac5f0cefeaeed5ca7ee3539.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](https://i-blog.csdnimg.cn/blog_migrate/3c8c3581fc5a18cf68c84fa4acb8f873.jpeg)
这个 arrOfPromises
的最大长度是什么?
const arrOfPromises = [];
Promise.all(arrOfPromises).then(/* */);
首先我们要知道 JavaScript 无论在Nodejs, 还是 Browser里面运行. 目前的机制还是单线程(Single Thread). (这边文章不参与WebWorker, ServiceWorker的讨论, 谢谢.)
其次理解: Parallel 和 Concurrent的概念区别
![93dc359769e1729acb1d33c6e6ec5116.png](https://i-blog.csdnimg.cn/blog_migrate/e21b35faa6ee7e43b119e8d821be2fe8.jpeg)
关键点就是这个: 这里的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 供各位参考:
- async - Documentation
- What is the best way to limit concurrency when using ES6's Promise.all()?
更多的优雅写法就需要各位自己去探索了, 欢迎留言点赞转发. 谢谢!!
![446e0f535b0a2beb2e4a9147a23062c8.png](https://i-blog.csdnimg.cn/blog_migrate/c1c838ca1184b6d230048d5d9b7ad540.jpeg)