节点js:等待100个请求完成

时间:2017-12-02 07:23:21

标签: javascript node.js

我有以下代码。它遍历一组id并为每个id发出请求。我希望在完成所有请求后执行一些代码 - 比如100.如何做到这一点?

function initRequest(url){
  request.get(topPostsUrl, function(err,response,body){
    if(err) throw err;
    handlePosts(body);
  })
}

function handlePosts(posts){
  var postsArray = JSON.parse(posts);
  for(var i=0; i < postsCount; i++){
      var targetUrl = itemUrl.replace("**id**", postsArray[i]);
      request.get(targetUrl, function(err,response,body){
        if(err) throw err;
        processOutput(body,i+1);
      })
    }
}

function calthisFunctionAfterAllRequests () {

}

4 个答案:

答案 0 :(得分:1)

使用Promises(MDN)和Promise.allMDN)函数等待所有请求的简单解决方案。

function initRequest(url){
  request.get(topPostsUrl, function(err,response,body){
    if(err) throw err;
    handlePosts(body).then(calthisFunctionAfterAllRequests);
  })
}
function doRequest(url) {
  return new Promise(function(resolve, reject) {
    request.get(url, function(err,response,body){
      if(err) return reject(err);
      return resolve(body);
    })
  })
}
function handlePosts(posts){
  var postsArray = JSON.parse(posts);
  var requests = [];
  for(var i=0; i < postsCount; i++) {
      var targetUrl = itemUrl.replace("**id**", postsArray[i]);
      requests.push(doRequest(targetUrl));
  }
  // here is magic
  return Promise.all(requests)
}

function calthisFunctionAfterAllRequests (requestsResult) {
    // results store in requestsResult array in same order they added
}

答案 1 :(得分:1)

npm install --save request-promise

然后

var rp = require('request-promise');

function initRequest(url){
  rp.get(topPostsUrl)
    .then(body => {
        handlePosts(body)
    })
    .catch(err => {
        throw err
    })
}



function handlePosts(posts){
  var postsArray = JSON.parse(posts)
  var arrayRequests = []
  for(var i=0; i < postsCount; i++){
    var targetUrl = itemUrl.replace("**id**", postsArray[i])
    arrayRequests.push(
        function(){
            return rp
                .get(targetUrl)
                .then(() => {
                    return true
                })
                .catch(err => {
                    throw err
                })
        }
    )
    new Promise
        .all(arrayRequests)
        .then(() => {
            calthisFunctionAfterAllRequests()
        })
        .catch(err => {
            throw err
        })
  }
}

function calthisFunctionAfterAllRequests () {

}

答案 2 :(得分:1)

Promise.all有两个缺点:

  1. 如果任何promise失败,它们都会失败(不会调用处理成功请求的函数)。

  2. 您的所有请求都会立即开始。如果您有一个100个网址的数组,那么您将发出100个请求,并可能使您的请求目标不满意或锁定其运行的计算机的网络流量。

  3. 要解决第1点问题,您可以创建一个承诺数组来处理拒绝(失败)并返回Fail个对象。处理结果时,您可以过滤掉失败的请求:

    const doRequest = url => 
      new Promise(
        (resolve, reject) =>
          request.get(
            url, 
            (err,response,body) =>
              (err)
                ? reject(err)
                : resolve(body)
          )
      );
    const Fail = function(reason){ this.reason = reason; }
    const handlePosts = posts =>
      Promise.all(
        (JSON.parse(posts))
        .map(
          post => post.replace("**id**", post)
        )
        .map(
          url => doRequest(url)
          .then(
            resolve=>resolve
            ,reject => new Fail(reject) //do not fail all requests just because one failed
          )
        )
      )
    
    doRequest(topPostsUrl)
    .then(
      handlePosts
    )
    .then(
      // you can filter out failed request by: results.filter(r=>(r && r.constructor)!==Fail)
      // you can filter out succeeded request by: results.filter(r=>(r && r.constructor)===Fail)
      calthisFunctionAfterAllRequests
    )
    

    第2点可以通过throttling处理活动请求的数量来处理:上面的代码看起来像这样:

    const max5 = throttle(5)
    const handlePosts = posts =>
      Promise.all(
        (JSON.parse(posts))
        .map(
          post => post.replace("**id**", post)
        )
        .map(
          url => max5(doRequest)(url)
          .then(
            resolve=>resolve
            ,reject => new Fail(reject) //do not fail all requests just because one failed
          )
        )
      )
    

答案 3 :(得分:0)

这是抽象代码表示。

function RequestAll() {

  for (var i = 1; i <= 100; i++) {
    initRequest();
  }
  // return a promise 
}


RequestAll.then(function() {
  //whatever you need to do
});