| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 | '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);};
 |