我正在尝试创建一个处理并行HTTP请求的队列。
为每个HTTP请求生成一个请求对象,例如
{
method: 'POST',
uri: 'http://posttestserver.com/post.php',
body: {
some: 'foo'
},
json: true
}
我传入了这些对象的数组,并希望将它们添加到队列中,然后执行实际的请求。
问题:Promise.all语句在返回之前等待所有请求完成。
问题:我希望将所有任务添加到队列中,并在每次请求完成后返回,而不是等待所有任务。任何人都可以建议如何分离逻辑以使请求从队列中添加任务?
注意:promise-queue和request-promise都返回promises。
以下是我所拥有的:
"use strict";
const Queue = require("promise-queue");
const rp = require('request-promise');
const maxConcurrent = 10;
const maxQueue = Infinity;
const queue = new Queue(maxConcurrent, maxQueue);
var options = [
{
method: 'POST',
uri: 'http://posttestserver.com/post.php',
body: {
some: 'foo'
},
json: true
},{
method: 'POST',
uri: 'http://posttestserver.com/post.php',
body: {
some: 'bar'
},
json: true
}
];
Promise.all(options.map(function(task) {
return queue.add(function() {
return rp(task);
})
}))
.then(function(response) {
log(response);
})
.catch(function(err) {
log(err);
});
function log(data) {
console.log(JSON.stringify(data, undefined, 4));
}
答案 0 :(得分:2)
我建议在forEach循环中调用promise链,如下所示:
var queueTask = function(task) {
// returns a promise
return queue.add(function() { return rp(task); });
};
var logResponse = function(response) {
console.log(response);
};
var catchErrors = function(err) {
console.log(err);
};
options.forEach(opt => {
queueTask()
.then(logResponse)
.catch(catchErrors);
})
<强>更新强>
在评论中提到,上面的代码片段并没有让您知道上一个任务何时完成。这不是原始问题的要求,但由于一些评论说它可能有用,这里有一种方法可以使用promises来实现:
var runTasks = new Promise(function(resolve, reject) {
var queueTask = function(task) {
// returns a promise
return queue.add(function() { return rp(task); });
};
var logResponse = function(response) {
console.log(response);
};
var catchErrors = function(err) {
console.log(err);
};
options.forEach((opt, i, arr) => {
queueTask()
.then(logResponse)
.catch(catchErrors);
if (i === arr.length-1) { resolve(); }
});
});
var functionToRunWhenLastTaskCompletes = function() {
console.log('All tasks are complete.');
};
// runTasks is a promise here, not a function
// so you don't need to call it like a function
runTasks
.then(functionToRunWhenLastTaskCompletes)