在NodeJS中使用q.all命名的promise结果

时间:2016-01-07 14:54:46

标签: node.js promise q

我对这个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参数中获得了承诺。

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

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:1)

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