NodeJS - 使用 Q 对对象数组执行异步操作,有点扭曲
Posted
技术标签:
【中文标题】NodeJS - 使用 Q 对对象数组执行异步操作,有点扭曲【英文标题】:NodeJS - using Q to do async operations on an array of objects, with a twist 【发布时间】:2014-10-11 22:22:57 【问题描述】:我也是 Q 和 promises 的新手,并且已经为这个问题苦苦挣扎了好几天。我正在尝试遍历一个可变长度的 RECORDS 数组,使用异步调用中每条记录的 ID 来检索 OBJECT(在 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()
合作,并建立一系列承诺等,但我完全感到困惑并怀疑/希望我可能会让这变得比需要的更难。
【问题讨论】:
【参考方案1】:不要使用您手动填写的全局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...
);
【讨论】:
谢谢!这完全有道理。我回到“末日金字塔”开始行动,但很快就会用这种方法换掉它。出于某种原因,我发现这个承诺的东西很奇怪。再次感谢! @DavidC.:很高兴能帮上忙。请accept the answer!以上是关于NodeJS - 使用 Q 对对象数组执行异步操作,有点扭曲的主要内容,如果未能解决你的问题,请参考以下文章
使用 std::atomic<int> 索引对大型数组进行异步并行化操作有多安全