在节点请求的循环中等待所有完成的请求
Wating for all finished request in a loop with node request
我使用节点请求 ajax 包。所以,我有一个循环,在每次迭代中它都会向我的服务器发出请求。
// realItems needs the complete value of items assigned
var realItems;
var items = [];
_.forEach(JSON.parse(body), (value, key) => {
request('myurl/' + id, (error, response, body) => {
items = JSON.parse(body)
});
});
我如何捆绑来自 request
包的所有请求,以便我可以将 items
变量的值分配给最后的 realItems
?
// 编辑:
我使用 React js,所以在这种情况下 realItems
是一个状态,我不能在每个循环迭代中触发它,因为渲染会在每个 setState
上触发
有多种方法可以解决这个问题。这是一个不保留结果顺序的蛮力方法:
var items = [];
var cnt = 0;
_.forEach(JSON.parse(body), (value, key) => {
++cnt;
request('myurl/' + value.id, (error, response, body) => {
items.push(JSON.parse(body));
// if all requesets are done
if (--cnt === 0) {
// process items here as all results are done now
}
});
});
这是一个使用 Bluebird 承诺的版本:
var Promise = require('bluebird');
var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);
var promises = [];
_.forEach(JSON.parse(body), (value, key) => {
promises.push(request('myurl/' + value.id));
});
Promise.all(promises).then(function(results) {
// all requests are done, data from all requests is in the results array
// and are in the order that the requests were originally made
});
而且,这里有一个使用 Bluebird 迭代器的更简单的 Bluebird promises 方法:
var Promise = require('bluebird');
var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);
Promise.map(JSON.parse(body), function(value) {
return request('myurl/' + value.id);
}).then(function(results) {
// all requests are done, data is in the results array
});
是否要求您使用 request
包?我使用类似的 async
并附带一个 parallel
方法,它完全符合您的要求 -
https://github.com/caolan/async#parallel
示例:
async.parallel([
function(callback){
setTimeout(function(){
callback(null, 'one');
}, 200);
},
function(callback){
setTimeout(function(){
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results){
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});
我使用节点请求 ajax 包。所以,我有一个循环,在每次迭代中它都会向我的服务器发出请求。
// realItems needs the complete value of items assigned
var realItems;
var items = [];
_.forEach(JSON.parse(body), (value, key) => {
request('myurl/' + id, (error, response, body) => {
items = JSON.parse(body)
});
});
我如何捆绑来自 request
包的所有请求,以便我可以将 items
变量的值分配给最后的 realItems
?
// 编辑:
我使用 React js,所以在这种情况下 realItems
是一个状态,我不能在每个循环迭代中触发它,因为渲染会在每个 setState
有多种方法可以解决这个问题。这是一个不保留结果顺序的蛮力方法:
var items = [];
var cnt = 0;
_.forEach(JSON.parse(body), (value, key) => {
++cnt;
request('myurl/' + value.id, (error, response, body) => {
items.push(JSON.parse(body));
// if all requesets are done
if (--cnt === 0) {
// process items here as all results are done now
}
});
});
这是一个使用 Bluebird 承诺的版本:
var Promise = require('bluebird');
var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);
var promises = [];
_.forEach(JSON.parse(body), (value, key) => {
promises.push(request('myurl/' + value.id));
});
Promise.all(promises).then(function(results) {
// all requests are done, data from all requests is in the results array
// and are in the order that the requests were originally made
});
而且,这里有一个使用 Bluebird 迭代器的更简单的 Bluebird promises 方法:
var Promise = require('bluebird');
var request = Promise.promisify(require("request"));
Promise.promisifyAll(request);
Promise.map(JSON.parse(body), function(value) {
return request('myurl/' + value.id);
}).then(function(results) {
// all requests are done, data is in the results array
});
是否要求您使用 request
包?我使用类似的 async
并附带一个 parallel
方法,它完全符合您的要求 -
https://github.com/caolan/async#parallel
示例:
async.parallel([
function(callback){
setTimeout(function(){
callback(null, 'one');
}, 200);
},
function(callback){
setTimeout(function(){
callback(null, 'two');
}, 100);
}
],
// optional callback
function(err, results){
// the results array will equal ['one','two'] even though
// the second function had a shorter timeout.
});