How to call function after completion of async functions inside loop?

后端 未结 2 1305
南方客
南方客 2021-01-06 20:46

I have a forEach loop in NodeJS, iterating over a series of keys, the values of which are then retrieved asynchronously from Redis. Once the loop and retrieval has complete,

相关标签:
2条回答
  • 2021-01-06 21:17

    No lib is needed. Easy as pie, it's just an async loop. Error handling is omitted. If you need to do a parallel async loop use a counter.

    exports.awesomeThings = function(req, res) {
        client.lrange("awesomeThings", 0, -1, function(err, awesomeThings) {
            var len = awesomeThings.length;
            var things = [];
            (function again (i){
                if (i === len){
                    //End
                    res.send(JSON.stringify(things));
                }else{
                    client.hgetall("awesomething:"+awesomeThings[i], function(err, thing) {
                        things.push(thing);
    
                        //Next item
                        again (i + 1);
                    })
                }
            })(0);
    });
    
    0 讨论(0)
  • 2021-01-06 21:20

    I use Bluebird promises here. Note how the intent of the code is rather clear and there is no nesting.

    First, let's promisify the hgetall call and the client -

    var client = Promise.promisifyAll(client);
    

    Now, let's write the code with promises, .then instead of a node callback and aggregation with .map. What .then does is signal an async operation is complete. .map takes an array of things and maps them all to an async operation just like your hgetall call.

    Note how Bluebird adds (by default) an Async suffix to promisifed methods.

    exports.awesomeThings = function(req, res) {
        // make initial request, map the array - each element to a result
        return client.lrangeAsync("awesomeThings", 0, -1).map(function(awesomeThing) {
           return client.hgetallAsync("awesomething:" + awesomeThing);
        }).then(function(things){ // all results ready 
             console.log(things); // log them
             res.send(JSON.stringify(things)); // send them
             return things; // so you can use from outside
        });
    };
    
    0 讨论(0)
提交回复
热议问题