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.
		
		
		
		
		
			
		
			
				
					73 lines
				
				2.5 KiB
			
		
		
			
		
	
	
					73 lines
				
				2.5 KiB
			| 
											3 years ago
										 | 'use strict'; | ||
|  | 
 | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |     value: true | ||
|  | }); | ||
|  | exports.default = ensureAsync; | ||
|  | 
 | ||
|  | var _setImmediate = require('./internal/setImmediate'); | ||
|  | 
 | ||
|  | var _setImmediate2 = _interopRequireDefault(_setImmediate); | ||
|  | 
 | ||
|  | var _initialParams = require('./internal/initialParams'); | ||
|  | 
 | ||
|  | var _initialParams2 = _interopRequireDefault(_initialParams); | ||
|  | 
 | ||
|  | var _wrapAsync = require('./internal/wrapAsync'); | ||
|  | 
 | ||
|  | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
|  | 
 | ||
|  | /** | ||
|  |  * Wrap an async function and ensure it calls its callback on a later tick of | ||
|  |  * the event loop.  If the function already calls its callback on a next tick, | ||
|  |  * no extra deferral is added. This is useful for preventing stack overflows | ||
|  |  * (`RangeError: Maximum call stack size exceeded`) and generally keeping | ||
|  |  * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
 | ||
|  |  * contained. ES2017 `async` functions are returned as-is -- they are immune | ||
|  |  * to Zalgo's corrupting influences, as they always resolve on a later tick. | ||
|  |  * | ||
|  |  * @name ensureAsync | ||
|  |  * @static | ||
|  |  * @memberOf module:Utils | ||
|  |  * @method | ||
|  |  * @category Util | ||
|  |  * @param {AsyncFunction} fn - an async function, one that expects a node-style | ||
|  |  * callback as its last argument. | ||
|  |  * @returns {AsyncFunction} Returns a wrapped function with the exact same call | ||
|  |  * signature as the function passed in. | ||
|  |  * @example | ||
|  |  * | ||
|  |  * function sometimesAsync(arg, callback) { | ||
|  |  *     if (cache[arg]) { | ||
|  |  *         return callback(null, cache[arg]); // this would be synchronous!!
 | ||
|  |  *     } else { | ||
|  |  *         doSomeIO(arg, callback); // this IO would be asynchronous
 | ||
|  |  *     } | ||
|  |  * } | ||
|  |  * | ||
|  |  * // this has a risk of stack overflows if many results are cached in a row
 | ||
|  |  * async.mapSeries(args, sometimesAsync, done); | ||
|  |  * | ||
|  |  * // this will defer sometimesAsync's callback if necessary,
 | ||
|  |  * // preventing stack overflows
 | ||
|  |  * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); | ||
|  |  */ | ||
|  | function ensureAsync(fn) { | ||
|  |     if ((0, _wrapAsync.isAsync)(fn)) return fn; | ||
|  |     return (0, _initialParams2.default)(function (args, callback) { | ||
|  |         var sync = true; | ||
|  |         args.push(function () { | ||
|  |             var innerArgs = arguments; | ||
|  |             if (sync) { | ||
|  |                 (0, _setImmediate2.default)(function () { | ||
|  |                     callback.apply(null, innerArgs); | ||
|  |                 }); | ||
|  |             } else { | ||
|  |                 callback.apply(null, innerArgs); | ||
|  |             } | ||
|  |         }); | ||
|  |         fn.apply(this, args); | ||
|  |         sync = false; | ||
|  |     }); | ||
|  | } | ||
|  | module.exports = exports['default']; |