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.
		
		
		
		
		
			
		
			
				
					
					
						
							98 lines
						
					
					
						
							2.8 KiB
						
					
					
				
			
		
		
	
	
							98 lines
						
					
					
						
							2.8 KiB
						
					
					
				'use strict'; | 
						|
 | 
						|
function isPromise(obj) { | 
						|
  return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'; | 
						|
} | 
						|
 | 
						|
/** | 
						|
 * Return a function that will run a function asynchronously or synchronously | 
						|
 * | 
						|
 * example: | 
						|
 * runAsync(wrappedFunction, callback)(...args); | 
						|
 * | 
						|
 * @param   {Function} func  Function to run | 
						|
 * @param   {Function} cb    Callback function passed the `func` returned value | 
						|
 * @return  {Function(arguments)} Arguments to pass to `func`. This function will in turn | 
						|
 *                                return a Promise (Node >= 0.12) or call the callbacks. | 
						|
 */ | 
						|
 | 
						|
var runAsync = module.exports = function (func, cb) { | 
						|
  cb = cb || function () {}; | 
						|
 | 
						|
  return function () { | 
						|
 | 
						|
    var args = arguments; | 
						|
 | 
						|
    var promise = new Promise(function (resolve, reject) { | 
						|
      var resolved = false; | 
						|
      const wrappedResolve = function (value) { | 
						|
        if (resolved) { | 
						|
          console.warn('Run-async promise already resolved.') | 
						|
        } | 
						|
        resolved = true; | 
						|
        resolve(value); | 
						|
      } | 
						|
 | 
						|
      var rejected = false; | 
						|
      const wrappedReject = function (value) { | 
						|
        if (rejected) { | 
						|
          console.warn('Run-async promise already rejected.') | 
						|
        } | 
						|
        rejected = true; | 
						|
        reject(value); | 
						|
      } | 
						|
 | 
						|
      var usingCallback = false; | 
						|
      var callbackConflict = false; | 
						|
      var contextEnded = false; | 
						|
 | 
						|
      var answer = func.apply({ | 
						|
        async: function () { | 
						|
          if (contextEnded) { | 
						|
            console.warn('Run-async async() called outside a valid run-async context, callback will be ignored.'); | 
						|
            return function() {}; | 
						|
          } | 
						|
          if (callbackConflict) { | 
						|
            console.warn('Run-async wrapped function (async) returned a promise.\nCalls to async() callback can have unexpected results.'); | 
						|
          } | 
						|
          usingCallback = true; | 
						|
          return function (err, value) { | 
						|
            if (err) { | 
						|
              wrappedReject(err); | 
						|
            } else { | 
						|
              wrappedResolve(value); | 
						|
            } | 
						|
          }; | 
						|
        } | 
						|
      }, Array.prototype.slice.call(args)); | 
						|
 | 
						|
      if (usingCallback) { | 
						|
        if (isPromise(answer)) { | 
						|
          console.warn('Run-async wrapped function (sync) returned a promise but async() callback must be executed to resolve.'); | 
						|
        } | 
						|
      } else { | 
						|
        if (isPromise(answer)) { | 
						|
          callbackConflict = true; | 
						|
          answer.then(wrappedResolve, wrappedReject); | 
						|
        } else { | 
						|
          wrappedResolve(answer); | 
						|
        } | 
						|
      } | 
						|
      contextEnded = true; | 
						|
    }); | 
						|
 | 
						|
    promise.then(cb.bind(null, null), cb); | 
						|
 | 
						|
    return promise; | 
						|
  } | 
						|
}; | 
						|
 | 
						|
runAsync.cb = function (func, cb) { | 
						|
  return runAsync(function () { | 
						|
    var args = Array.prototype.slice.call(arguments); | 
						|
    if (args.length === func.length - 1) { | 
						|
      args.push(this.async()); | 
						|
    } | 
						|
    return func.apply(this, args); | 
						|
  }, cb); | 
						|
};
 | 
						|
 |