繁体   English   中英

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

[英]NodeJS Promise, how to spread/slow http.get calls

我是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);
        })
    })    
});

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);
});
linkArray.forEach(function(element) {
        .....
    })

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

您可以使用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());
      }
    });
}

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

  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()) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM