【问题标题】:NodeJS - using Q to do async operations on an array of objects, with a twistNodeJS - 使用 Q 对对象数组执行异步操作,有点扭曲
【发布时间】: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() 合作,并建立一系列承诺等,但我完全感到困惑并怀疑/希望我可能会让这变得比需要的更难。

【问题讨论】:

    标签: arrays node.js asynchronous promise q


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2022-11-29
    相关资源
    最近更新 更多