Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/support - Empty taskset -> final callback automatically fired on next tick? #1402

Closed
ORESoftware opened this issue Apr 13, 2017 · 3 comments
Labels

Comments

@ORESoftware
Copy link
Contributor

ORESoftware commented Apr 13, 2017

Say we are using async.map or really almost any of the async utilities

My question/feature request is - if the task array/set is empty, does async fire the final callback on the next tick? If not, is there a way to tell async to do that? Would be a nice feature.
Otherwise, I have a lot of this in my code, which is more verbose:

async.map([], function(item,cb){

}, function final(err, results){
    process.next(function(){ 
      cb(err,results);
   });
});

to avoid Zalgo, this above is necessary, but, it is a lot nicer to do:

async.map([], function(item,cb){

}, cb);

I guess one thing we could is check if the array is empty, and if so, return early with

if(![].length){
   return process.next(cb);
}

what do yall recommend?

@hargasinski
Copy link
Collaborator

Hey @ORESoftware, thanks for the question! For an empty array/set, async invokes the final callback on the same tick as built-in deferrals were removed in v2.0.0 for performance reasons (I don't think async < v2.0.0 even had a built-in deferral for this case though).

A simple workaround is wrapping async.map in async.ensureAsync:

async.ensureAsync(async.map)([], function(item, cb) {

}, cb);

or somewhere at beginning of your code:

const asyncMap = async.ensureAsync(async.map);
// then call `asyncMap` just as you would `async.map`

Otherwise, the process.nextTick approach you proposed is perfectly valid. Although, if you are writing code that might get used in a browser, you should take a look at async.setImmediate or async.nextTick.

@aearly
Copy link
Collaborator

aearly commented Apr 16, 2017

Yep, @hargasinski has it on the money. We do not protect you from Zalgo for performance reasons.

One simplification you can do is:

function final(err, results){
    process.nextTick(cb, err, results);
}

async.nextTick/async.setImmediate/process.nextTick/setImmediate all let you pass args that will be passed to the function.

@aearly aearly closed this as completed Apr 16, 2017
@ORESoftware
Copy link
Contributor Author

ORESoftware commented Apr 16, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants