简体   繁体   中英

Async.each :only one callback after all executed

I have an async.each function to the following things in an order.

1.Get image size from array.

2.Crop the image.

3.Upload to AWS s3.

Now i want to show single success message after all upload.

async.each(crop_sizes,function (result,cb) {
    //crop image
    gm(path)
            .resize(result.width, result.height,'^')
            .crop(result.width, result.height)
            .stream(function (err,buffer) {
                //upload to s3
             s3.upload(params,function(err,success){
                   if(!errr){
                     conseole.log(uploaded);
                    }
                })
            });

  });

It output like

uploaded
uploaded
uploaded
uploaded

But i want to show success message after all upload is it possible with async

Async.each takes a 3rd augment which is:

A callback which is called when all iteratee functions have finished, 
or an error occurs. Invoked with (err).

You will want to setup that third argument to know when all the uploads have completed or if some have failed.

https://caolan.github.io/async/docs.html#each

(1) When you work async.js in general, you should always trigger the callback ie cb when your task completes or even when there is an error. It should also be once and no more for each task. If you don't trigger it or trigger it more than once within the same task, your code might hang or you will get an error, respectively.

(2) async.each has 3 arguments: coll , iteratee , callback . You only use 2. The last argument callback is triggered when all tasks are completed.

async.each(crop_sizes, function task(result, cb) {
    //crop image
    gm(path)
        .resize(result.width, result.height, '^')
        .crop(result.width, result.height)
        .stream(function (err, buffer) {
            if (err)
                return cb(err); // we use 'return' to stop execution of remaining code
            //upload to s3
            s3.upload(params, function(err,success){
                if (err)
                    return cb(err);
                cb(null, success);
            });

            // you could also simply do s3.upload(params, cb);
        });
}, function allTasksAreDone (err) {
    if (err)
        console.log(err);
    // do something now
});

(3) I think if you want to get the result of each task, you're better off using async.map . here is an example . The only difference is that your callback will have an additional argument given which is an array of all your success es.

I think you should try to wait for each "each" return and then console.log if you think everything is fine. Inside your async.each , except with a complicated code you wont be able to know that every "each" worked well

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM