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?
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
.
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.
Oh nice, I did not know that about process.nextTick, etc, that's awesome
Most helpful comment
Yep, @hargasinski has it on the money. We do not protect you from Zalgo for performance reasons.
One simplification you can do is:
async.nextTick
/async.setImmediate
/process.nextTick
/setImmediate
all let you pass args that will be passed to the function.