NodeJS Promise,如何传播/减慢http.get调用

时间:2018-04-02 07:18:59

标签: javascript node.js

我是NodeJS和Promise功能的新手,所以如果这是一个无知的问题,请保持礼貌。

我正在尝试首先读取记录数据库,然后检查实际工作的链接(寻找200响应)。对于我当前的测试数据,这应该总是返回200响应。我收到302(请求太多)响应,然后开发服务器崩溃。我需要减慢我通过请求发送到数据库的方式,但我无法弄清楚如何做到这一点。在我看来,承诺只是在解决后立即发送所有内容。

我已尝试在当时的部分建立时间延迟,但无济于事。这是代码:

var http404Promise = new Promise(function(resolve, reject) {
        var linkArray = new Array()

        db.sequelize.query(photoQuery, {
            replacements: queryParams
        }).spread(function(photoLinks) {
            photoLinks.forEach(function(obj) {
                var siteLink = hostname + 'photo/' + obj.img_id
                linkArray.push(siteLink)

                //console.log(siteLink);
            });

            resolve(linkArray);
        });
    });

http404Promise.then(function(linkArray) {
    linkArray.forEach(function(element) {
        console.log(element);
        http.get(element, function(res) {
            console.log(element);
            console.log("statusCode: ", res.statusCode); // <======= Here's the status code
        }).on('error', function(e) {
            console.log(element);
            console.error(e);
        })
    })    
});

4 个答案:

答案 0 :(得分:2)

forEach中的正常超时不起作用的原因是forEach不等待超时完成。因此,每个请求都会同时等待,并且您不会得到您想要的惊人效果 但是,您可以使用每个元素的索引来计算超时。

linkArray.forEach(function(element, index) {
    setTimeout(function() {
        console.log(element);
        http.get(element, function(res) {
            console.log(element);
            console.log("statusCode: ", res.statusCode); // <======= Here's the status code
        }).on('error', function(e) {
            console.log(element);
            console.error(e);
        });
    }, index * 500);
});

答案 1 :(得分:1)

linkArray.forEach(function(element) {
        .....
    })

此处您可以使用Async eachLimit来执行一些请求,而不是forEach。您还可以编写代码,以便在上一个请求完成之后完成下一个请求或使用Async eachSeries但是对于eachLimit,您有一些并行性。

答案 2 :(得分:1)

您可以将async模块用于此

https://github.com/caolan/async

或者如果您希望使用当前代码,则需要更改以下

linkArray = [];
var counter = 0;
http404Promise.then(function(responseData) {
  linkArray  = responseData;
  if (linkArray.length > 0) {
    requestHandler(linkArray.pop());
  }
});

function requestHandler(data) {
  http
    .get(data, function(res) {
      counter++;
      if (counter == linkArray.length) {
        console.log("finished");
      } else {
        reuqestCheckPromiss(linkArray.pop());
      }
    })
    .on("error", function(e) {
      counter++;
      if (counter == linkArray.length) {
        console.log("finished");
      } else {
        reuqestCheckPromiss(linkArray.pop());
      }
    });
}

答案 3 :(得分:0)

您可以使用reduce函数创建延迟请求管道

&#13;
&#13;
    const timeout = 500;
    const linkArray = [1,2,3,4]
    
    const httpFunc = el => {
      // your http function here
      console.log('request num ', el)
    }
    
    
    const func = el => new Promise(resolve => {
      setTimeout(() => {
        resolve(httpFunc(el));
      }, timeout)
    })
    
    linkArray.reduce((acc, el) => acc.then(() => func(el)), Promise.resolve())
&#13;
&#13;
&#13;