【问题标题】:NodeJs : Multiple loop of HTTP requests execute simultaneouslyNodeJs:HTTP请求的多个循环同时执行
【发布时间】:2019-09-18 06:20:13
【问题描述】:

nodejs multiple http requests in loop

根据上面的问题,回答了如何使用一组 url 执行 http 请求的循环,效果很好。但我想要实现的是执行另一个 http 请求循环,这应该只在之后完成第一个循环的完成(即它应该等待 http 请求的第一个循环完成。

// Import http
var http = require('http');

// First URLs array
var urls_first = ["http://www.google.com", "http://www.example.com"];

// Second URLs array
var urls_second = ["http://www.yahoo.com", "http://www.fb.com"];

var responses = [];
var completed_requests = 0;

function performHTTP(array) {
for (i in urls_first) {
        http.get(urls[i], function(res) {
            responses.push(res);
            completed_requests++;
            if (completed_requests == urls.length) {
                // All download done, process responses array
                console.log(responses);
            }
        });
    }
 }

在上面的 sn-p 中,我添加了另一个 urls 数组。我将 for 包装在一个函数中,以在每次调用时更改数组。由于我必须等待第一个循环完成,我尝试了 async/await如下所示。

async function callMethod() { 
    await new Promise (resolve =>performHTTP(urls_first)))   // Executing function with first array
    await new Promise (resolve =>performHTTP(urls_second)))  // Executing function with second array
} 

但在这种情况下,两个函数调用同时执行(即)它不等待第一个数组执行完成。两个执行同时发生,我只需要在一个完成后发生。

【问题讨论】:

  • 你可以使用promise、callback、async await或eachSeries、async库。我更喜欢:caolan.github.io/async/v3/docs.html#eachSeries
  • 我认为 await 将等待任何先前的 await 完成。因为我想要几个循环,所以回调会很复杂。相反,我什至尝试使用 .then 没有像`var promise1 = await new Promise (resolve =>performHTTP(urls_first)) promise1.then(await new Promise (resolve =>performHTTP(urls_second)))`

标签: javascript node.js async-await


【解决方案1】:

您需要在 Promise 中提出您的请求:

function request(url) {
    return new Promise((resolve, reject) => {
       http.get(url, function(res) {
        // ... your code here ... //
        // when your work is done, call resolve to make your promise done
         resolve()
       });
    }
}

然后解决您的所有请求

// Batch all your firts request in parallel and wainting for all
await Promise.all(urls_first.map(url => request(url)));
// Do the same this second url
await Promise.all(urls_second.map(url => request(url)));

注意,此代码未经测试,可能存在一些错误,但主要原理在这里。

更多关于 Promise 的信息:https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Promise

【讨论】:

  • 试过了,只有第一个 await 有效,第二个 await 不行
【解决方案2】:

查看如何在第一个完成后立即使用.then() 调用第二个 performHttp。

【讨论】:

  • 在 .then 中调用函数对我不起作用。
【解决方案3】:

您可以使用 eachSeries 调用服务。

https://www.npmjs.com/package/async-series

series([
  function(done) {
    console.log('First API Call here')
    done() // if you will pass err in callback it will be caught in error section.
  },
  function(done) {
    console.log('second API call here')
    done()
  },
  function(done) {
    // handle success here
  }
], function(err) {
  console.log(err.message) // "another thing"
})

【讨论】:

    猜你喜欢
    • 2018-05-03
    • 1970-01-01
    • 1970-01-01
    • 2015-11-25
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多