节点承诺;记住每个(顺序)步骤

时间:2016-12-22 21:03:11

标签: javascript node.js promise q

我希望使用Q库为节点做两件事。

1)发出许多异步查询,每个查询都使用前一个查询的结果 2)一旦完成所有查询,就可以访问每个查询的结果

E.g。让我们说一个数据库有一个城市,每个城市都有一个城市,每个城市都有一个州,每个州都有一个国家。考虑到骑行,我想一次打印出所有这些地理数据。

var ridingObj = // Already have access to this database object

ridingObj.getRelated('city')
    .then(function(cityObj) {
        // Have access to cityObj.getField('name');
        return cityObj.getRelated('state');
    })
    .then(function(stateObj) {
        // Have access to stateObj.getField('name');
        return stateObj.getRelated('country');
    })
    .then(function(countryObj) {
        // Have access to countryObj.getField('name');
        // Can't console.log anything but the country, because we no longer have access :(
    })

使用这种模式,我可以访问所有数据,但不能同时访问。

什么被认为是一次性获取所有数据的干净,传统模式?

2 个答案:

答案 0 :(得分:2)

我在多个场合看到的一种简单方法是逐步写入位于周围范围内的对象,然后从承诺链末尾的对象中读取:

var ridingObj = ...;
var result = {};

ridingObj.getRelated('city')
    .then(function(cityObj) {
        result.city = cityObj;                // write city
        return cityObj.getRelated('state');
    })
    .then(function(stateObj) {
        result.state = stateObj;              // write state
        return stateObj.getRelated('country');
    })
    .then(function(countryObj) {
        result.country = countryObj;          // write country
        console.log(result);                  // read all
    })

答案 1 :(得分:1)

这是我想到的一种很酷的方式。

它使用更高范围的变量,但它没有副作用,它允许您访问所有结果作为函数的参数 - 看起来很干净。

var p = queryForRiding();
Q.spread([
    p,
    p = p.then(function(riding) { return riding.getRelated('city'); }),
    p = p.then(function(city) { return city.getRelated('state'); }),
    p = p.then(function(state) { return state.getRelated('country'); })
], function(riding, city, state, country) {
    console.log(riding, city, state, country);
});