2017-10-07 93 views
-1

我有一个拥有20000+个承诺的大集合,我想用Bluebird的Promise.map来解决它。但是,我的代码不能成功执行,但在大约15-20分钟后超时。Nodejs Bluebird Promise.map不适用于大集合

我得到的错误是超时错误。

当集合少于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

您可能会尝试太多的并发连接,这可能会耗尽本地资源或压倒目标。我建议在'Promise.map()'中使用'concurrency'选项。首先将它设置为像10这样的小东西,如果可以的话,然后试着提高它。 – jfriend00

+0

此外,现在你已经添加了代码,这是使用'Promise.map()'的错误方法。通常情况下,您会传递一组数据和一个函数,对该数据执行一些异步操作并返回一个承诺。你不会传递一系列的承诺。我们可以使用'Promise.all()'和一组promise。 – jfriend00

+0

您显示的代码没有任何意义,因为'promise.length'为'0',所以'for'循环将不会执行任何操作。 – jfriend00

回答

0

如果您收到超时错误,那么你可能只是压倒了太多的并发请求的一些主机目标服务器。对于大量请求,您需要同时限制同时发送多少个同时请求到同一个主机。我建议一次开始时限制在5-10左右,然后你可以尝试提高它,看看它是否能够提高你的表现。目标服务器对同时有多少个同时请求可以同时提供全部服务的限制。高于这个数字只会加重基础设施负担,最终导致超时错误。

Bluebird的Promise.map()正确使用时(你没有做)有一个concurrency选项,它会告诉它你希望它立即使用的最大并发连接数。但是,要使用该选项,必须正确使用Bluebird.map(),并在其中传递一组数据(而不是您已经开始异步操作的承诺数组)以及返回承诺的函数这些数据项之一。

下面是如何正确使用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 
}); 
+0

感谢您的回复。我将尝试更新代码以处理数据数组而不是承诺。但是,如果我有一系列的承诺,有没有办法与他们合作,除了promises.all? – user2434285

+1

@ user2434285 - 一个promise数组通常表示一组已经启动的异步操作。在那个时候,除了当Promise.all()所做的事情完成时,没有什么可以了解的。您需要一种不会一次启动太多异步操作的解决方案。 – jfriend00

相关问题