在节点请求的循环中等待所有完成的请求

Wating for all finished request in a loop with node request

本文关键字:请求 节点 循环 等待      更新时间:2023-09-26

我使用节点请求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
    }
  });
});

这是一个使用蓝鸟承诺的版本:

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 promises方法它使用了一个Bluebird迭代器:

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平行

的例子:

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.
});