我目前正在尝试输入下面的数组phoneNumbers。示例数组有2个电话号码,工作正常,但我的实际数组包含数千个数字。
当我尝试使用promise.all并将电话号码映射到名称时,我收到连接错误,因为它花了这么长时间。如何使用promises(或类似的东西)在阵列中一次使用50或100?
var phoneNumbers = [4444444444, 5555555555];
var answer = client.Answer;
return Promise.all(phoneNumber.map(id => Answer.findThing(id, {
attributes: ["name", "state"]
}))).then(problems => {
for (var p = 0; p < problems.length; p++) {
var phoneNames = problems[p].name;
}
})
答案 0 :(得分:0)
尝试这样的事情:
var promises = [];
for (var i = 0; i < phoneNumbers.length; i++) {
(function () {
var def = new $.Deferred();
promises.push(def);
var j = i;
asyncFunction(phoneNumbers[j]).then(function (data) {
//do whatever here
def.resolve();
})
})();
}
var completePromise= $.when.apply(undefined, promises).promise();
当已解决completedPromise时,您知道所有电话号码都已由______ asyncFunction处理。它应该允许同时处理许多,虽然我只在生产中使用几百而不是数千运行此代码。
答案 1 :(得分:0)
在这些行之间进行读取,看起来你想要返回一个名字数组的承诺。
如果是这样,您可以按如下方式整理代码:
// ES6 native Promise
// n parallel requests
var phoneNumbers = [4444444444, 5555555555, ...];
var findOptions = { 'attributes': ['name', 'state'] };
return Promise.all(phoneNumbers.map(id => client.Answer.findThing(id, findOptions))).then(problems => problems.map(p => p.name));
这只是整理,而不是解决方案。
如果phoneNumbers
数组的长度确实是您的错误的来源,那么您需要尝试限制同时挂起的.findThing()
请求的数量。最简单的方法(至少在诊断上)是使用Bluebird的.map()及其concurrency
选项。
// Bluebird
// n requests but a maximum of 10 (or whatever) concurrently
var phoneNumbers = [4444444444, 5555555555, ...];
var findOptions = { 'attributes': ['name', 'state'] };
var mapOptions = {concurrency: 10}; //adjust up/down experimentally
return Promise.map(phoneNumbers, id => client.Answer.findThing(id, findOptions), mapOptions).map(p => p.name);
使用原生Promise可以实现相同的效果,但代码不会那么整洁。
如果您发现只有{concurrency: 1}
有效,那么Bluebird&#39; Promise.map
就是矫枉过正。顺序请求很容易使用本机Promise进行编码:
// ES6 native Promise
// n sequential requests, by building .then chain
var phoneNumbers = [4444444444, 5555555555, ...];
var findOptions = { 'attributes': ['name', 'state'] };
return phoneNumbers.reduce((promise, id) => promise.then(() => client.Answer.findThing(id, findOptions)), Promise.resolve()).then(problems => problems.map(p => p.name));
这可能太缺乏记忆力;如果是这样,那么递归替代方案会更好:
// ES6 native Promise
// n sequential requests, through recursion
var phoneNumbers = [4444444444, 5555555555, ...];
var findOptions = { 'attributes': ['name', 'state'] };
function find(index, results) {
return (index < phoneNumbers.length) ? client.Answer.findThing(phoneNumbers(index), findOptions).then(p => {
results.push(p.name);
return find(index+1, results);
}) : results;
}
return find(0, []);