从下面的代码我试图解决这个承诺,只有在游戏对象从api循环中填充数据之后才有意义但是它仍然显示为空:
{
info: summoner,
matchIds: { << used for loop below
0: matchIds['matches'][0].matchId,
1: matchIds['matches'][1].matchId,
2: matchIds['matches'][2].matchId,
3: matchIds['matches'][3].matchId,
4: matchIds['matches'][4].matchId,
5: matchIds['matches'][5].matchId,
6: matchIds['matches'][6].matchId,
7: matchIds['matches'][7].matchId,
8: matchIds['matches'][8].matchId,
9: matchIds['matches'][9].matchId
}
}
var getMatches = function(summoner) {
var promise = new Promise(function(resolve, reject){
var opt = {};
var games = {}; << object needs to be filled
for (var val in Object.keys(summoner['matchIds'])) {
var match = summoner['matchIds'][val];
opt.id = match;
api.getMatchById(opt, function(err, game) {
games[x] = game;
})
}
console.log(games);
resolve({games});
});
return promise;
};
答案 0 :(得分:1)
您的代码假设api.getMatchById()
是同步的,但可能不是,因此for
循环在您的任何api.getMatchById()
调用完成之前就已完成,因此当您进行游戏时,游戏始终为空解决。您必须跟踪所有api.getMatchById()
次呼叫的完成时间,并且只有在发生这种情况时才会解决。
对此进行编码的最佳方式是宣传api.getMatchById()
,然后使用Promise.all()
跟踪他们何时完成。如果您不打算这样做,那么您可以创建一个手动计数器:
var getMatches = function(summoner) {
return new Promise(function(resolve, reject){
var cntr = 0;
var opt = {};
var games = {};
var keys = Object.keys(summoner['matchIds']);
keys.forEach(function(key) {
var match = summoner['matchIds'][key];
opt.id = match;
api.getMatchById(opt, function(err, game) {
// need some error handling here
games[x] = game;
++cntr;
// when all api calls are done, resolve
if (cntr === keys.length) {
resolve({games});
}
})
});
});
};
另外,请不要使用for / in来迭代数组的项目,因为它可能容易出问题。在ES6中,您可以使用for / of。我在这里使用.forEach()
。
答案 1 :(得分:0)
如果使用可能的解决方案,不是纯粹的承诺,而是bluebird
库
const Promise = require('bluebird');
const promise = new Promise(function (resolve, reject) {
const propsPromise = {};
Object.keys(summoner['matchIds']).forEach(val => {
const match = summoner['matchIds'][val];
propsPromise[match] = new Promise((resolve, reject) => {
api.getMatchById(opt, (err, game) => {
if (err) {
return reject(err);
}
resolve(game);
});
});});
return Promise.props(propsPromise);
});
只要对象将通过内容解析,您的承诺就会得到解决。
文档链接 - Promise.props