我非常接近完成这个功能的基础但是我被卡住了,而且我对承诺缺乏了解而且我正在学习它们如何运作等等。关于我的问题,我正在循环一些数据然后存储在一个Array中,该Array将通过promise链传递给另一个函数,但是数组正在填充挂起的promises,我只需要放入数组中的promise中的实际数据,请参阅下面的内容,了解最新进展情况于:
var getGameData = function(matchIdArray) {
var promise = new Promise(function(resolve,reject) {
console.log('Start getGameData');
s3.headObject({Bucket: 'lolsearchgames', Key: '347341'}, function(err, result) {
console.log('Checking Bucket');
if (err && err.code === 'NotFound') {
console.log('Bucket data Not Found!')
var gameData = new Array();
for (var i = 0; i < matchIdArray.length; i++) {
gameData.push(new Promise(function(res, rej) {
lolapi.Match.get(matchIdArray[i], function (error, gamedata) {
if (error) {
rej(error);
}
if (gamedata) {
console.log('Pushing new data to Array! ' + gamedata.matchId);
res(gamedata);
}
})
}));
}
if (gameData.length === 10) {
console.log(gameData);
resolve(gameData);
}
} else {
console.log('Bucket data Found!');
}
})
});
return promise;
console.log('End getGameData');
};
答案 0 :(得分:2)
使用Promise.all等待所有&#34; gameData&#34;如下 - 也使用Array#map来避免必须推送到数组
注意:但是,如果在任何lolapi.Match.get承诺中有任何拒绝,Promise.all将拒绝 - 这可能不是您想要的,我不确定您的代码示例
var getGameData = function getGameData(matchIdArray) {
var promise = new Promise(function (resolve, reject) {
console.log('Start getGameData');
s3.headObject({ Bucket: 'lolsearchgames', Key: '347341' }, function (err, result) {
console.log('Checking Bucket');
if (err && err.code === 'NotFound') {
console.log('Bucket data Not Found!');
Promise.all(matchIdArray.map(function(matchId) {
return new Promise(function (res, rej) {
lolapi.Match.get(matchId, function (error, gamedata) {
if (error) {
rej(error);
}
res(gamedata);
});
})
}))
.then(resolve)
.catch(reject);
} else {
console.log('Bucket data Found!');
reject('Bucket data Found!');
}
});
});
console.log('End getGameData');
return promise.then(function (results) { // see note below
return results.filter(function (result) {
return result;
});
});
};
替代方案 - 我认为&#34;整洁&#34;代码
var getGameData = function getGameData(matchIdArray) {
return new Promise(function(resolve, reject) {
console.log('Start getGameData');
s3.headObject({
Bucket: 'lolsearchgames',
Key: '347341'
}, function(err, result) {
console.log('Checking Bucket');
if (err && err.code === 'NotFound') {
console.log('Bucket data Not Found!');
resolve();
} else {
console.log('Bucket data Found!');
reject('Bucket data Found!');
}
});
}).then(function() {
return Promise.all(matchIdArray.map(function(matchId) {
return new Promise(function(res, rej) {
lolapi.Match.get(matchId, function(error, gamedata) {
if (error) {
rej(error);
}
res(gamedata);
});
})
}));
}).then(function (results) { // see note below
return results.filter(function (result) {
return result;
});
});
}
如果您使用Bluebird承诺,它有实用方法来实现&#34; promisify&#34;节点回调样式函数 - 在下面的代码中,s3.headObjectAsync
是s3.headObject
的保护版本,lolapi.Match.getAsync
是lolapi.Match.get
你会看到,使用bluebirds promisify,(和ES2015 +箭头符号,因为你正在使用节点)使你的代码更加紧凑
var getGameData = function getGameData(matchIdArray) {
return s3.headObjectAsync({
Bucket: 'lolsearchgames',
Key: '347341'
})
// do some gymnastics, because if there's no error, that should reject
// but if the error is "NotFound" that should resolve
.then(results => {
throw {code: 'Bucket data Found!'};
})
.catch(err => {
if (err && err.code === "NotFound") {
return; // this is OK
}
throw err;
})
.then(() => Promise.all(matchIdArray.map(matchId => lolapi.Match.getAsync(matchId))))
.then(results => results.filter(result => result)); // see note below
}
在ES5代码中,上面仍然非常紧凑
var getGameData = function getGameData(matchIdArray) {
return s3.headObjectAsync({
Bucket: 'lolsearchgames',
Key: '347341'
}).then(function (results) {
throw { code: 'Bucket data Found!' };
}).catch(function (err) {
if (err && err.code === "NotFound") {
return; // this is OK
}
throw err;
}).then(function () {
return Promise.all(matchIdArray.map(function (matchId) {
return lolapi.Match.getAsync(matchId);
}));
}).then(function (results) { // see note below
return results.filter(function (result) {
return result;
});
});
};
请注意,在所有这些答案中,结果并不完全符合原始代码所期望的结果。在您的原始代码中,如果
返回的承诺中的空结果gamedata
是假的,您只是忽略了&#34; Match.get&#34; ...但是,你不能用Promises做到这一点 - 最后一个。然后在答案中过滤掉getGameData