我有以下代码片段接受数据数组,对数组中的每个项执行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 **/ }
}
]
我遇到的问题是,我不知道如何调用提供的回调方法,使代码在执行前等待所有http.get
操作完成。
如何达到预期效果?
答案 0 :(得分:4)
您可以对所有请求使用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
数组对应的一个参数。
答案 1 :(得分:1)
你可以测试returnData的长度,当它与你拥有它的所有玩家的长度相匹配时,你可以回调。我还建议您查看异步模块https://www.npmjs.com/package/async或转换为使用promise并使用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!
}
});
});
});
}
答案 2 :(得分:1)
使用async + promises:
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
}