1

So, I've been beating this one about for a few days and I'm stumped as to what is the best way to solve it. I am using Waterline/dogwater with HAPI and trying to do something broadly like so:-

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

The trouble I have is the code will always ding before it outputs the trouser colors. This is because, as much as I understand it, _.each will make the code go async. I tried to introduce Promises (bluebird), but without luck. I even looked at generators (Co), but my node version is fixed at pre v0.11.

I'd like to perform some database look-ups within the _.each, return these results (if any) to the trouser object, which can then be returned:-

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

What is the best way to do this as efficiently as possible?

Help is appreciated. Happy to return here and focus the question where needed.

4

1 回答 1

5

Well_.each 与异步性无关。这只是一种下划线/lodash 的方式trousers.forEach(...)

您的问题在于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');
        });
    });
});
于 2014-11-13T16:05:06.480 回答