Closed
Description
Composing sync and async methods gets a little hairy. Consider a case where you're performing a waterfall of some methods, but one in the middle is synchronous. You have to do something like this:
async.waterfall(
[
asyncMethod1,
asyncMethod2,
]
function (error, data) {
if (error) {
// handle error
}
else {
var nextData = syncMethod3(data);
async.waterfall(
[
async.apply(asyncMethod4, data),
asyncMethod5
],
function (error, data) {
if (error) {
// handle error, probably in the same way as before
}
else {
doSomething(data);
}
}
);
}
}
);
I think this could be improved with the addition of a simple asyncify
method. This method could take a synchronous function as an argument and return an asynchronous version. The returned function would invoke the original function or caught errors to the callback. Here is a naive implementation:
function asyncify (fn) {
return function () {
var callback = arguments[fn.length]
try {
var returnValue = fn.apply(null, Array.prototype.slice.call(arguments, 0, fn.length));
setImmediate(function () {
callback(null, returnValue);
});
}
catch (e) {
return callback(e);
}
}
}
With this, we can clean up the original code significantly:
async.waterfall(
[
asyncMethod1,
asyncMethod2,
async.asyncify(syncMethod3),
asyncMethod4,
asyncMethod5
],
function (error, data) {
if (error) {
// handle error
}
else {
doSomething(data);
}
}
)
Could something like this be added as an async method?