我有一个拥有20000多个承诺的大型集合,我想使用Bluebird的Promise.map解决它。但是我的代码没有成功执行,但在大约15-20分钟后超时。
我得到的错误是超时错误。
当集合的承诺少于2000时,代码会在不到10秒的时间内成功执行。
请帮助我找到Promise.map的替代方法或任何其他方式,以便代码不会超时。
service.getSomePromises().then(function(arrSomePromises){
var promises = [];
for (var i = 0;i < arrSomePromises.length; i++){
var getDetailsObject = _getDetails(_db, i);
promises.push(getDetailsObject);
}
//Below is the code that times out
return Promise.map(promises, function(doc){
return reportData.push(doc);
})
}
答案 0 :(得分:1)
如果您收到超时错误,那么您可能只是压倒了那个目标服务器,同时向某个主机发出了太多请求。对于大量请求,您需要限制同时向同一主机传输的同时请求数。我建议一次开始限制大约5-10,然后你可以尝试提高它,看看它是否真的能提高你的表现。目标服务器对可以同时为所有服务提供服务的同时请求数量有限制。高于此值只会给基础架构带来负担,最终只会导致超时错误。
Bluebird的Promise.map()
如果使用得当(您没有这样做)有一个concurrency
选项,它会告诉它您希望它一次使用的最大并发连接数。但是,要使用该选项,您必须正确使用Bluebird.map()
,在其中传递一个数据数组(不是您已经开始执行异步操作的Promise数组)和一个函数返回对其中一个数据项进行操作的promise。
以下是如何使用Promise.map()
选项正确使用concurrency
的示例。
let someLargeArrayOfData = [...];
Promise.map(someLargeArrayOfData, function(item) {
return request(item); // async function that returns promise
}, {concurrency: 10}).then(function(results) {
// results is an array of data from all the resolved promises
}).catch(function(err) {
// process error here
});