SailsJS Nested callback in async waterfall functio

2019-09-02 07:55发布

问题:

I'm creating an application with SailsJS. I have a question about using callbacks within an Async waterfall and Async each.

I've got two functions inside an async waterfall function. The first callback returns the correct value. The second function has a nested callback. However, the value of the nested callback is stuck within the waterline find function, and never gets returned to the outer function.

Do you know how I could return the value to the outer function?

Thanks for your help.

myFunction: function (req,res) {
async.waterfall([
    function(callback){
        // native MongoDB search function that returns an Array of Objects
    },
    function(result, callback){
        async.each(resultAll, function (location){
            Model.find({location:'56d1653a34de610115d48aea'}).populate('location')
            .exec(function(err, item, cb){
                console.log (item) // returns the correct value, but the value cant be passed to the outer function
            })
        })
        callback(null, result);
    }], function (err, result) {
        // result is 'd'
        res.send (result)
    }
)}

回答1:

When you use async's function you should you should use you callback once you are done with operations you want to perform. for example:

async.waterfall([
    function(cb1){
        model1.find().exec(function(err,rows1){
            if(!err){
                model2.find({}).exec(function(err,rows2){
                    var arr=[rows1,rows2];
                    cb1(null,arr);
                });
            }else
                cb1(err);
        })
    },function(arr,cb2){
    /**
     * here in the array....we will find the array of rows1 and rows2 i.e.[rows1,rows2]
     * */
        model3.find().exec(err,rows3){
            if(!err){
                arr.push(rows3);
            //  this arr will now be [rows1,rows2,rows3]
            }
            else
                cb2(err);
        }
        cb1(null,arr);
    }],
    function(err,finalArray){
        if(err){
        //  error handling
        }
        else{
        /**
         * in finalArray we have [rows1,rows2] ,rows3 is not there in final array
         * beacause cb2() was callbacked asynchronously with model3.find().exec() in second function
         */
        }
    });

so according to me your code should be like

async.waterfall([
        function(callback){
            // native MongoDB search function that returns an Array of Objects
        },
        function(result, callback){
            async.each(resultAll, function (location){
                Model.find({location:'56d1653a34de610115d48aea'}).populate('location')
                    .exec(function(err, item, cb){
                        console.log (item) // returns the correct value, but the value cant be passed to the outer function
                        callback(null, yourData);
                        /**
                         * yourData is the data whatever you want to recieve in final callbacks's second parameter
                         * i.e. callback(null,item) or callback(null,[result,item]) or callback(null,result)
                        */
                    })
            })
        }], function (err, result) {
        // result is 'd'
        res.send (result)
    }
);

Apply this and you can see things you want in your final callback.