我也是Q和Promise的新手,并且已经为这个问题苦苦挣扎了好几天。我试图使用异步调用中每个记录的ID来遍历RECORDS的可变长度数组,以检索对象(在Redis的情况下)。
我需要将RECORD中的某些数据与检索到的OBJECT中的某些数据进行组合,然后从这些组合对象中创建一个新数组,然后将其返回。
我失败的代码如下所示:
arrayOfThingRecords = [... an array of small objects, each with a 'thingid'...];
arrayOfCombinedObjects = [];
arrayOfThingRecords.forEach(function(thingRecord) {
Q.ninvoke(redisClient, "HGETALL", thingRecord.thingid)
.then((function (thingObject) {
combinedThingObject = {
thingStuffFromRecord: thingRecord.thingStuffFromRecord,
thingStuffFromObject: thingObject.thingStuffFromObject
};
}).done(function () {
arrayOfCombinedObjects.push(combinedThingObject)
}); //
}; // Then do stuff with arrayOfThingObjects...
我知道使用forEach
是错误的,因为它会在诺言返回之前执行。我一直在尝试与Q.all()
和Q.settled()
,以及建立一系列的Promise等,但是我完全感到困惑和怀疑/希望我可能会为此加倍努力。
不要使用arrayOfCombinedObjects = []
您手动填写的全局变量。始终用相应操作的结果值来兑现您的承诺。例如,
Q.ninvoke(redisClient, "HGETALL", thingRecord.thingid)
.then(function(thingObject) {
return {
// ^^^^^^
thingStuffFromRecord: thingRecord.thingStuffFromRecord,
thingStuffFromObject: thingObject.thingStuffFromObject
};
});
成为一个承诺用于该对象。
现在,使用Q.all
是正确的方法。它接受一个promise数组,并将它们组合为一个所有结果数组的promise。因此,我们需要构建一个Promise数组-从上面对这些对象的Promise数组。您可以使用forEach
迭代并将push
数组放在一起,但是使用起来map
要容易得多。然后变成
var arrayOfThingRecords = [... an array of small objects, each with a 'thingid'...];
var arrayOfPromises = arrayOfThingRecords.map(function(thingRecord) {
return Q.ninvoke(redisClient, "HGETALL", thingRecord.thingid)
// ^^^^^^ let the promise be part of the new array
.then(function(thingObject) {
return {
thingStuffFromRecord: thingRecord.thingStuffFromRecord,
thingStuffFromObject: thingObject.thingStuffFromObject
};
});
});
Q.all(arrayOfPromises).then(function(arrayOfCombinedObjects) {
// Then do stuff with arrayOfThingObjects...
});
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句