多个 Http 请求被调用并存储在一个数组中,但是如何等到所有请求完成后再使用数组

问题描述 投票:0回答:4

我有一个想要循环的值数组。这些值中的每一个都将用于向服务器发出 http 请求。我将从服务器收到每个请求的响应。我想将所有这些响应存储在一个数组中,然后在 ALL 请求完成后对数组进行处理。由于我的代码的异步性质,我不确定如何使应用程序等待所有请求完成。发生的情况是我正在发出请求,但由于异步性质,我想要对数组执行的工作在所有请求完成之前就已经开始了。我怎样才能使这段代码“同步”,因为它会等到所有请求完成后才开始使用 listOfResponses 数组

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
list.forEach(function(word) {

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
  });
});


/* ******************************* 
HERE I WANT TO DO STUFF WITH listOfResponses ONCE ALL THE REQUESTS FINISH
********************************** */
javascript node.js asynchronous
4个回答
6
投票

只需将其映射到一系列承诺:

  const promises = list.map(word => new Promise(resolve => {
   var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
   request(url, {
     json: true
   }, (err, res) => {
     if (err) {
       return reject(err);
     }   
     resolve(res.body);
   });
 }));

然后你可以使用

Promise.all
获得所有结果:

 Promise.all(promises).then(results => {
  //...
 });

3
投票

每次请求结束时只需检查响应:

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
list.forEach(function(word) {

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + word;
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
    check();
  });
});

// CHECK THE LIST
function check() {
  if (listOfResponses.length == list.length) {
    console.log("YAY! Here you have your responses", listOfResponses);
  }
}

1
投票

这是一个异步场景,实现此目的的一种方法是递归调用一个函数,该函数将循环遍历您的

list
单词。递归根据服务器的每个响应进行。

另一种方法是使用 Promise

看这个代码片段(递归方法):

//import the require library to make http requests to a server
const request = require('request');

//values to be sent via a restful GET request 
const list = [
  'value_one',
  'value_two'
];

//store resoonses from GET request
var listOfResponses = [];

//loop through the list
var loop = function(array, index, cb) {  
  if (index === array.length)
      cb();
      return;

  //Make a rest GET call to a server
  var url = 'http://notsurehowtomakethisworksoiamaskingstackoverflow.com/api/words/' + array[i];
  request(url, {
    json: true
  }, (err, res, body) => {
    if (err) {
      return console.log(err);
    }

    //store the response from the server into out array
    listOfResponses.push(body.response);
    loop(array, i++, cb);
  });
};

loop(list, 0, function() {
      /* ******************************* 
         HERE I WANT TO DO STUFF WITH listOfResponses ONCE ALL THE REQUESTS FINISH
       ********************************** */
});       

如您所见,循环从使用

loop
调用
index = 0
函数开始,每个响应都将调用具有递增索引的
loop
函数。

index == list.length
时递归结束,并执行回调以保持逻辑流程。


0
投票

2023 年,我写了 sync-request-curl。该库将帮助使用 libcurl 的 Easy 界面发送同步 HTTP 请求。

该库包含原始 sync-request 中功能的子集,但利用 node-libcurl 以获得更好的性能和 NodeJS 的附加 libcurl 选项。

这是 GET 请求的简单用法:

// import request from 'sync-request-curl';
const request = require('sync-request-curl');
const response = request('GET', 'https://ipinfo.io/json');
console.log('Status Code:', response.statusCode);
console.log('body:', response.body.toString());
console.log('json:', JSON.parse(response.body.toString());

这是一个更接近您的用例的示例:

const request = require('sync-request-curl');

const list = [
  '1',
  '2',
  '3',
];

const listOfResponses = [];

list.forEach((word) => {
  const url = `https://dummyjson.com/products/${word}`;
  console.log(url);
  const response = request('GET', url);

  if (response.statusCode === 200) {
    const jsonBody = JSON.parse(response.body.toString('utf-8'));
    listOfResponses.push(jsonBody.title);
  } else {
    console.error(`Error for word '${word}': ${response.statusCode}`);
  }
});

console.log(listOfResponses);

这给了我们预期的结果:

https://dummyjson.com/products/1
https://dummyjson.com/products/2
https://dummyjson.com/products/3
[ 'iPhone 9', 'iPhone X', 'Samsung Universe 9' ]

希望这有帮助:)。

© www.soinside.com 2019 - 2024. All rights reserved.