在 NodeJS 中使用 q.all 命名承诺结果

Named promise results with q.all in NodeJS

我对这个 q 有点陌生,我觉得它非常棒,但有些东西我还是不明白。

我通过传递 q.all 一系列承诺,设法 运行 一些与 q.all 的组合承诺。像这样..

var promises = [promiseOne(), promiseTwo()];
q.all(promises).then(function (results) {
    res.send(results);
} );

问题是我实际上希望这些承诺被命名,所以我不必依赖承诺的顺序。

我在某处读到,您实际上可以将对象传递给 q.all,以命名结果。所以这将是这样的:

var promises = { promiseOne: promiseOne(), promiseTwo: promiseTwo() }
q.all(promises).then(function(results){
    res.send(results);
});

但我想这与发送数组的方式不同,因为我没有在其中获得我的承诺结果。我得到的结果与此类似:

{
    promiseOne: {
        source: {}
    },
    promiseTwo: {
        source: {}
    }
}

那么您将如何从 q.all 中获取命名结果?

需要注意的一件事是,我将在 promises 数组中拥有的承诺数量不是固定的,因为我是从用户发送到我的函数的 GET 参数中获得的。

此外,在我的每个承诺中,我都有另一个要解决的承诺数组(或对象),我也想命名其结果。

Q.js 似乎不提供 Q.all(object),因此您需要在传递给 Q.all()

之前将对象映射到数组

像这样的东西可以重复使用而且很方便:

Q.allObj = function (obj) {
    var array = Object.keys(obj).map(function(key, i) {
        try {
            //expect a promise
            return obj[key].then(function(value) {
                return {key: key, value: value};
            });
        } 
        catch(e) { 
            // whoops it was a value
            return {key: key, value: obj[key]};
        }
    });
    return Q.all(array);
};

使用如下:

Q.allObj(myObj).then(function(results) {
    results.forEach(function(obj) {
        var name = obj.key;
        var value = obj.value;
        ...
    });
});

这是使用您要求的功能(return 一个对象)编写 Roamer 编写的代码的另一种方法:

Q.props = obj => {
    const ps = Q.all(Object.keys(obj).map(x => Q.all([x, obj[x]])));
    return ps.then(x => x.reduce((p, c) => {p[c[0]] = c[1]; return p } , {}));
};

哪个会让你做:

Q.props(promises).then(o => {
    o.promiseOne
});

尽管如果您需要所有这些辅助函数,您应该考虑使用 bluebird。