Javascript 返回前从多个HTTP Get请求获取数据
我有以下代码片段,它接受数据数组,对数组中的每个项执行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';
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()的结果传递给它。我对解决方案的理解正确吗?是的,就是这样。