Skip to content

Commit

Permalink
added async.asyncify. closes #671
Browse files Browse the repository at this point in the history
  • Loading branch information
aearly committed Jun 28, 2015
1 parent a95455c commit e794801
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

New Features:
- Added `constant`
- Added `asyncify`/`wrapSync` for making sync functions work with callbacks. (#671, #806)
- `retry` now accepts an `interval` parameter to specify a delay between retries. (#793)
- `async` should work better in Web Workers due to better `root` detection (#804)
- Callbacks are now optional in `whilst`, `doWhilst`, `until`, and `doUntil` (#642)
Expand Down
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ Usage:
* [`unmemoize`](#unmemoize)
* [`ensureAsync`](#ensureAsync)
* [`constant`](#constant)
* [`asyncify`](#asyncify)
* [`wrapSync`](#wrapSync)
* [`log`](#log)
* [`dir`](#dir)
* [`noConflict`](#noConflict)
Expand Down Expand Up @@ -1785,6 +1787,29 @@ async.auto({
---------------------------------------
<a name="asyncify">
<a name="wrapSync">
### asyncify(func)
*Alias: wrapSync*
Take a sync function and make it async, passing its return value to a callback. This is useful for plugging sync functions into a waterfall, series, or other async functions. Any arguments passed to the generated function will be passed to the wrapped function (except for the final callback argument). Errors thrown will be passed to the callback.
__Example__
```js
async.waterfall([
async.apply(fs.readFile, filename, "utf8"),
async.asyncify(JSON.parse),
function (data, next) {
// data is the result of parsing the text.
// If there was a parsing error, it would have been caught.
}
], callback)
```
---------------------------------------
<a name="log" />
### log(function, arguments)
Expand Down
15 changes: 15 additions & 0 deletions lib/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,21 @@
};
};

async.wrapSync =
async.asyncify = function asyncify(func) {
return function (/*args..., callback*/) {
var args = _baseSlice(arguments);
var callback = args.pop();
var result;
try {
result = func.apply(this, args);
} catch (e) {
return callback(e);
}
callback(null, result);
};
};

// Node.js
if (typeof module !== 'undefined' && module.exports) {
module.exports = async;
Expand Down
45 changes: 45 additions & 0 deletions test/test-async.js
Original file line number Diff line number Diff line change
Expand Up @@ -4069,3 +4069,48 @@ exports['constant'] = function (test) {
test.done();
});
};

exports['asyncify'] = {
'asyncify': function (test) {
var parse = async.asyncify(JSON.parse);
parse("{\"a\":1}", function (err, result) {
test.ok(!err);
test.ok(result.a === 1);
test.done();
});
},

'variable numbers of arguments': function (test) {
async.asyncify(function (x, y, z) {
test.ok(arguments.length === 3);
test.ok(x === 1);
test.ok(y === 2);
test.ok(z === 3);
})(1, 2, 3, function () {});
test.done();
},

'catch errors': function (test) {
async.asyncify(function () {
throw new Error("foo");
})(function (err) {
test.ok(err);
test.ok(err.message === "foo");
test.done();
});
},

'dont catch errors in the callback': function (test) {
try {
async.asyncify(function () {})(function (err) {
if (err) {
return test.done(new Error("should not get an error here"));
}
throw new Error("callback error");
});
} catch (e) {
test.ok(e.message === "callback error");
test.done();
}
}
};

0 comments on commit e794801

Please sign in to comment.