【问题标题】:Named promise results with q.all in NodeJS在 NodeJS 中使用 q.all 命名的 promise 结果
【发布时间】:2016-04-12 00:34:54
【问题描述】:

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

我设法通过传递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.allQ.all 的结果将始终是一个数组
  • @thefourtheye 这是我发现blog.500tech.com/really-you-can-do-that-with-promises 的地方,如果#2 他似乎正在这样做(并不是说这是一个值得信赖的资源)。此外,在 q 的 Angular 文档中,它声明 promise 可以是一个对象 docs.angularjs.org/api/ng/service/$q 。不确定 AngularJS 的 q 是否与 Node 的相同。
  • Q.js documentation 没有表明Q.all() 将接受对象代替数组。作为一种解决方法,我建议您找到一种方法,将所需的名称作为解析每个承诺的值的一部分。
  • @Roamer-1888 是的,这就是我现在所处的位置。我返回一个对象,其名称为承诺解析中的键名。然后我把 q.all 返回的数组也变成了一个对象。但我希望 Q 有一种更清洁的方式来做到这一点。
  • 另一种可以工作的方法(如果情况允许)是利用三个数组的一致性:(1)一个数据数组,(2)映射数据数组产生的 Promises 数组,(3)Q.all() 提供的结果数组。如果存在这种情况,那么当循环遍历结果数组时(并且数据数组在范围内并且仍然完好无损),每个原始数据项及其结果都通过数组索引关联。

标签: node.js promise q


【解决方案1】:

这是另一种编写 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。

【讨论】:

  • 不错!不知道蓝鸟!使用 bluebird vs q 有什么缺点吗?
  • @lascort 这是一个较新的库 - 就是这样。 Q 有一个更易读的来源。就是这样。
  • 完美!刚刚让它和蓝鸟一起工作!谢谢你的精彩。我认为接受这个答案并不好,因为它实际上并不建议蓝鸟。但是,如果您发布答案,那么绿色的东西就是您的了。
  • @lascort 我假设你不知道我与 bluebird 和 Q 的关系 - 但我添加了这条线来娱乐你 :)
  • 我想不出一个不使用蓝鸟的理由。为什么要重新发明轮子?
【解决方案2】:

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;
        ...
    });
});

【讨论】:

    猜你喜欢
    • 2017-11-23
    • 2023-03-05
    • 2017-06-02
    • 2019-03-27
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 2017-08-04
    相关资源
    最近更新 更多