Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 返回前从多个HTTP Get请求获取数据_Javascript_Node.js - Fatal编程技术网

Javascript 返回前从多个HTTP Get请求获取数据

Javascript 返回前从多个HTTP Get请求获取数据,javascript,node.js,Javascript,Node.js,我有以下代码片段,它接受数据数组,对数组中的每个项执行HTTP GET请求,并在执行提供的回调方法之前将返回的数据加载到新数组中: function(players, callbackMethod) { var returnData = []; players.forEach(function(item){ var playerRequestUrl = baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats';

我有以下代码片段,它接受数据数组,对数组中的每个项执行HTTP GET请求,并在执行提供的回调方法之前将返回的数据加载到新数组中:

function(players, callbackMethod) { 
   var returnData = [];  
   players.forEach(function(item){
       var playerRequestUrl = baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats';
       https.get(playerRequestUrl, function(res){
           res.on('data', function(chunk){
               var playerData = JSON.parse(chunk);
               returnData.push({"username":item.username, "data":playerData.raw[item.blazeId]});

               //callback here?                            
           });
       });
   });
}

本质上,它需要一组对象,如下所示:

[
    {
      "username":"user1",
      "blazeId":"guid1"
    },
    {
       "username":"user2",
       "blazeId":"guid2"
    }
]
[
   {
      "username":"user1",
      "data": { /** response data **/ }
   },
   {
      "username":"user2",
      "data": { /** response data **/ }
   }
]
并返回如下所示的对象数组:

[
    {
      "username":"user1",
      "blazeId":"guid1"
    },
    {
       "username":"user2",
       "blazeId":"guid2"
    }
]
[
   {
      "username":"user1",
      "data": { /** response data **/ }
   },
   {
      "username":"user2",
      "data": { /** response data **/ }
   }
]
我遇到的问题是,我不知道如何调用提供的回调方法,使代码在执行之前等待所有
http.get
操作完成


我如何才能达到预期的结果

您可以对所有请求使用
Promise.all
,这些请求一旦解决,就会调用回调:

function getAllPlayers(players, callbackMethod) {
  Promise.all(players.map((item) => {
    const playerRequestUrl = baseUrl + '/' + platform + '/members/' + item.blazeId + '/stats';
    return new Promise((resolve) => {
      https.get(playerRequestUrl, function(res) {
        res.on('data', function(chunk) {
          const playerData = JSON.parse(chunk);
          resolve({
            "username": item.username,
            "data": playerData.raw[item.blazeId]
          });
        });
      });
    });
  }))
    .then(callbackMethod)
}

请注意,在此实现中,
callbackMethod
应接受一个与
returnData
数组对应的参数。

您可以使用
Promise。所有
请求一旦解决,就会调用回调:

function getAllPlayers(players, callbackMethod) {
  Promise.all(players.map((item) => {
    const playerRequestUrl = baseUrl + '/' + platform + '/members/' + item.blazeId + '/stats';
    return new Promise((resolve) => {
      https.get(playerRequestUrl, function(res) {
        res.on('data', function(chunk) {
          const playerData = JSON.parse(chunk);
          resolve({
            "username": item.username,
            "data": playerData.raw[item.blazeId]
          });
        });
      });
    });
  }))
    .then(callbackMethod)
}

注意,在这个实现中,
callbackMethod
应该接受一个与您的
returnData
数组对应的参数。

您可以测试returnData的长度,当它与播放器的长度匹配时,您就拥有了所有的参数,并且可以回调。我还建议您看看异步模块,或者看看如何转换为使用Promission和使用Promise.all

function(players, callbackMethod) { 
   var returnData = [];
   players.forEach(function(item){
       var playerRequestUrl = baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats';
       https.get(playerRequestUrl, function(res){
           res.on('data', function(chunk){
               var playerData = JSON.parse(chunk);
               returnData.push({"username":item.username, "data":playerData.raw[item.blazeId]});
               if (returnData.length === players.length) {
                 //callback here!
               }                      
           });
       });
   });
}

您可以测试returnData的长度,当它与您拥有的所有播放器的长度匹配时,您可以回调它。我还建议您看看异步模块,或者看看如何转换为使用Promission和使用Promise.all

function(players, callbackMethod) { 
   var returnData = [];
   players.forEach(function(item){
       var playerRequestUrl = baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats';
       https.get(playerRequestUrl, function(res){
           res.on('data', function(chunk){
               var playerData = JSON.parse(chunk);
               returnData.push({"username":item.username, "data":playerData.raw[item.blazeId]});
               if (returnData.length === players.length) {
                 //callback here!
               }                      
           });
       });
   });
}
使用异步+承诺:

function requestPlayer (item, url) {
  return new Promise ((resolve, reject) => {
    https.get(playerRequestUrl, function(res){
        res.on('data', function(chunk){
            var playerData = JSON.parse(chunk);
            return resolve({"username":item.username, "data":playerData.raw[item.blazeId]})
        });
    });
  })
}

async function myFunction (players) {
  var returnData = []
  players.forEach(function(item){
    returnData.push(requestPlayer(item, baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats'))
  })
  var res = await Promise.all(returnData)
  // do whatever you want with your array of responses
}
使用异步+承诺:

function requestPlayer (item, url) {
  return new Promise ((resolve, reject) => {
    https.get(playerRequestUrl, function(res){
        res.on('data', function(chunk){
            var playerData = JSON.parse(chunk);
            return resolve({"username":item.username, "data":playerData.raw[item.blazeId]})
        });
    });
  })
}

async function myFunction (players) {
  var returnData = []
  players.forEach(function(item){
    returnData.push(requestPlayer(item, baseUrl+'/'+platform+'/members/'+item.blazeId+'/stats'))
  })
  var res = await Promise.all(returnData)
  // do whatever you want with your array of responses
}

由于这是一个学习项目,我愿意使用async/Await重写,我认为在某些情况下,使用此方法比链接太多承诺要好,并且您不需要编写“.then”(…)来执行下一个操作。我在我的node express服务器中广泛使用此方法来验证数据。由于这是一个学习项目,我愿意使用async/Await进行重写,我认为在某些情况下,使用此方法比链接太多承诺要好,并且您不需要编写“.then(…”)来执行下一个操作。我在我的node express服务器中广泛使用它来验证数据。出于好奇。。。我看到Promise是作为ECMAScript 2015规范的一部分添加的。是否正在计算结果?在此之前他们将如何解决此问题?!这是正确的,这种代码是过时的,我这样介绍它是因为它是使回调并行请求工作的最小更改,在任何其他解决方案的引擎盖下都有一个计数器,它只是隐藏的。这种代码的问题是错误处理变得复杂。。。我看到Promise是作为ECMAScript 2015规范的一部分添加的。是否正在计算结果?在此之前他们将如何解决此问题?!这是正确的,这种代码是过时的,我这样介绍它是因为它是使回调并行请求工作的最小更改,在任何其他解决方案的引擎盖下都有一个计数器,它只是隐藏的。这种代码的问题是错误处理变得复杂。工作非常完美。如果我理解正确:Promise.all()需要一组承诺。players.map()内部函数检索HTTP GET数据,并通过执行resolve()将数据返回给map()。然后在所有承诺都得到解决时调用(),并将players.map()的结果传递给它。我对解决方案的理解正确吗?是的,就是这样。效果很好。如果我理解正确:Promise.all()需要一组承诺。players.map()内部函数检索HTTP GET数据,并通过执行resolve()将数据返回给map()。然后在所有承诺都得到解决时调用(),并将players.map()的结果传递给它。我对解决方案的理解正确吗?是的,就是这样。