You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
110 lines
3.4 KiB
110 lines
3.4 KiB
'use strict'; |
|
|
|
Object.defineProperty(exports, "__esModule", { |
|
value: true |
|
}); |
|
exports.default = asyncify; |
|
|
|
var _isObject = require('lodash/isObject'); |
|
|
|
var _isObject2 = _interopRequireDefault(_isObject); |
|
|
|
var _initialParams = require('./internal/initialParams'); |
|
|
|
var _initialParams2 = _interopRequireDefault(_initialParams); |
|
|
|
var _setImmediate = require('./internal/setImmediate'); |
|
|
|
var _setImmediate2 = _interopRequireDefault(_setImmediate); |
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } |
|
|
|
/** |
|
* 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. |
|
* |
|
* If the function passed to `asyncify` returns a Promise, that promises's |
|
* resolved/rejected state will be used to call the callback, rather than simply |
|
* the synchronous return value. |
|
* |
|
* This also means you can asyncify ES2017 `async` functions. |
|
* |
|
* @name asyncify |
|
* @static |
|
* @memberOf module:Utils |
|
* @method |
|
* @alias wrapSync |
|
* @category Util |
|
* @param {Function} func - The synchronous function, or Promise-returning |
|
* function to convert to an {@link AsyncFunction}. |
|
* @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be |
|
* invoked with `(args..., callback)`. |
|
* @example |
|
* |
|
* // passing a regular synchronous function |
|
* 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); |
|
* |
|
* // passing a function returning a promise |
|
* async.waterfall([ |
|
* async.apply(fs.readFile, filename, "utf8"), |
|
* async.asyncify(function (contents) { |
|
* return db.model.create(contents); |
|
* }), |
|
* function (model, next) { |
|
* // `model` is the instantiated model object. |
|
* // If there was an error, this function would be skipped. |
|
* } |
|
* ], callback); |
|
* |
|
* // es2017 example, though `asyncify` is not needed if your JS environment |
|
* // supports async functions out of the box |
|
* var q = async.queue(async.asyncify(async function(file) { |
|
* var intermediateStep = await processFile(file); |
|
* return await somePromise(intermediateStep) |
|
* })); |
|
* |
|
* q.push(files); |
|
*/ |
|
function asyncify(func) { |
|
return (0, _initialParams2.default)(function (args, callback) { |
|
var result; |
|
try { |
|
result = func.apply(this, args); |
|
} catch (e) { |
|
return callback(e); |
|
} |
|
// if result is Promise object |
|
if ((0, _isObject2.default)(result) && typeof result.then === 'function') { |
|
result.then(function (value) { |
|
invokeCallback(callback, null, value); |
|
}, function (err) { |
|
invokeCallback(callback, err.message ? err : new Error(err)); |
|
}); |
|
} else { |
|
callback(null, result); |
|
} |
|
}); |
|
} |
|
|
|
function invokeCallback(callback, error, value) { |
|
try { |
|
callback(error, value); |
|
} catch (e) { |
|
(0, _setImmediate2.default)(rethrow, e); |
|
} |
|
} |
|
|
|
function rethrow(error) { |
|
throw error; |
|
} |
|
module.exports = exports['default']; |