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