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
			| 
											3 years ago
										 | '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']; |