将Promise.all
与异步代码一起使用时(如果是同步代码,没有什么可担心的),当你想发送一个问题时,你会遇到严重的性能(如果不是其他类型的话)鉴于异步操作的接收端(例如本地文件系统,HTTP服务器,数据库等等)没有优雅地处理那么多并行请求,整个请求(数十,数百,数千甚至数百万)请求
对于那种情况,如果我们可以告诉Promise.all
我们希望同时在飞行中有多少承诺,那将是完美的。但是,由于A +应该是精益的,添加这些奇特的功能肯定没有意义。
那么实现这一目标的更好方法是什么?
答案 0 :(得分:5)
嗯,首先 - 不可能给Promise.all
一个并发参数,因为promises代表已经启动操作,所以你不能在执行前排队或等待。
有限并发性要执行的是承诺返回函数。幸运的是 - bluebird使用Promise.map
:
Promise.map(largeArray, promiseReturningFunction, {concurrency: 16});
并发参数决定一次可以发生多少操作 - 请注意,这不是全局值 - 而是仅针对此链。例如:
Promise.map([1,2,3,4,5,6,7,8,9,10], function(i){
console.log("Shooting operation", i);
return Promise.delay(1000);
}, {concurrency: 2});
请注意,不保证执行顺序。
答案 1 :(得分:1)
由于我无法找到预先存在的库来处理承诺批处理,我自己写了一个简单的原语。它是一个包装要执行的function
数组的类,并将其分区为给定大小的批处理。它将等待每个批次完成后再运行下一个批次。这是一个相当天真的实现。在一些网络场景中,可能需要一个完整的限制机制。
代码:
/**
* Executes any number of functions, one batch at a time.
*
* @see http://jsfiddle.net/93z8L6sw/2
*/
var Promise_allBatched = (function() {
var Promise_allBatched = function(arr, batchSize) {
if (arr.length == 0) return Promise.resolve([]);
batchSize = batchSize || 10;
var results = [];
return _runBatch(arr, batchSize, results, 0)
.return(results); // return all results
};
function _runBatch(arr, batchSize, results, iFrom) {
// run next batch
var requests = [];
var iTo = Math.min(arr.length, iFrom + batchSize);
for (var i = iFrom; i < iTo; ++i) {
var fn = arr[i];
var request;
if (fn instanceof Function) {
request = fn();
}
else {
request = fn;
}
requests.push(request); // start promise
}
return Promise.all(requests) // run batch
.then(function(batchResults) {
results.push.apply(results, batchResults); // store all results in one array
console.log('Finished batch: ' + results.length + '/' + arr.length);
})
.then(function() {
if (iTo < arr.length) {
// keep recursing
return _runBatch(arr, batchSize, results, iTo);
}
});
}
return Promise_allBatched;
})();
答案 2 :(得分:-1)
let arry=[1,2,4,........etc];//large ammount of arry
while (arry.length) {
//I splice the arry 0,10...so you can change the limit as your //wish(note your server should be handle your limit
Promise.all(arry.splice(0, 10).map(async (eachArryElement) => {
let res = await yourAsyncMethod(eachArryElement);
}))
}
function yourAsyncMethod(data){
return new Promise((reslove,reject)=>{
//your logic
reslove('your output')
})
}