在bluebird承诺中执行异步操作

时间:2014-11-13 15:35:26

标签: node.js sails.js waterline bluebird hapijs

所以,我已经打了好几天了,我很难过,解决它的最佳方法是什么。我正在使用Waterline / dogwater和HAPI,并尝试做一些广泛的事情: -

wardrobe.find({WardrobeId: 5}).then(function(clothes) {
    //got my clothes in my wardrobe.
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) {
        //got my nice trousers
        _.each(trousers, function(trouser) {
            //logic to see if these are my pink trousers
            console.log('color?', trouser.color);
        });
        console.log('ding');
    });
});

我遇到的麻烦是代码在输出裤子颜色之前总是ding。这是因为,根据我的理解,_.each将使代码变为异步。我试图介绍Promises(蓝鸟),但没有运气。我甚至查看了生成器(Co),但我的节点版本在v0.11之前修复了。

我想在_.each内执行一些数据库查找,将这些结果(如果有的话)返回到trouser对象,然后返回: -

wardrobe.find({WardrobeId: 5}).then(function(clothes) {
    //got my clothes in my wardrobe.
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) {
        //got my nice trousers
        _.each(trousers, function(trouser) {
            //logic to see if these are my pink trousers
            db.colors.find({Color: trouser.color}).then(function(color) {
                //color here?
            });
        });
        console.log('ding');
    });
});

尽可能高效地完成这项工作的最佳方式是什么?

帮助表示赞赏。很高兴回到这里并将问题集中在需要的地方。

1 个答案:

答案 0 :(得分:5)

_.each与异步性无关。它只是执行trousers.forEach(...)的下划线/ lodash方式。

您的问题在于执行异步操作的db.colors.find方法。如果您希望它们按顺序执行,您可以链接这些方法:

wardrobe.find({WardrobeId: 5}).then(function(clothes) {
    //got my clothes in my wardrobe.
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) {
        //got my nice trousers
        var p = Promise.resolve();
        _.each(trousers, function(trouser) {
            //logic to see if these are my pink trousers
            p = p.then(function() {
                return db.colors.find({Color: trouser.color})
                    .then(function(color) {
                        // color here, they'll execute one by one
                    });
            });
        });
        p.then(function(){ 
            console.log('ding, this is the last one');
        });
    });
});

或者,如果您希望它们全部同时发生而不是等待前一个:

wardrobe.find({WardrobeId: 5}).then(function(clothes) {
    //got my clothes in my wardrobe.
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) {
        //got my nice trousers
        Promise.map(trousers, function(trouser) {
            return db.colors.find({Color: trouser.color});
        }).map(function(color){
            console.log("color", color);
        }).then(function(){ 
            console.log('ding, this is the last one');
        });
    });
});