jamestalmage/unpromisify

View on GitHub
index.js

Summary

Maintainability
A
1 hr
Test Coverage
(function () {
  var slice = Array.prototype.slice;

  var schedule = _setTimeout;

  if (typeof setImmediate === 'function') {
    schedule = _setImmediate;
  }

  if (('undefined' !== typeof process) && process && ('function' === typeof process.nextTick)) {
    schedule = _nextTick;
  }

  function callCallback(userCallback, ctx, args, done) {
    var syncResults = true;
    if (arguments.length === 2) {
      var opts = ctx;
      if ('function' === typeof ctx) {
        done = ctx;
        args = [];
        ctx = null;
      } else {
        done = opts.done;
        ctx = opts.ctx || null;
        args = opts.args || [];
        syncResults = opts.syncResults !== false;
      }
    }
    else if (arguments.length === 3) {
      done = args;
      args = ctx ? slice.call(ctx) : [];
      ctx = null;
    }
    else {
      if (arguments.length !== 4) {
        throw new Error('incorrect number of arguments: ' + arguments.length)
      }
      args = args ? slice.call(args) : [];
    }
    if ('function' !== typeof done) {
      throw new Error('done must be of type function, got: ' + typeof done);
    }

    var called = false;

    function handleCallback(err, result) {
      if (called) {
        return;
      }
      called = true;

      schedule(function () {
        done(err, result);
      });
    }

    args.push(handleCallback);

    var maybePromise = userCallback.apply(ctx, args);

    if (maybePromise && ('function' === typeof maybePromise.then)) {
      maybePromise.then(function (result) {
        handleCallback(null, result);
      }, handleCallback);
    } else if (syncResults && ('undefined' !== typeof maybePromise)) {
      schedule(function () {
        done(null, maybePromise);
      })
    }
  }

  callCallback.setScheduler = function setScheduler(newScheduler) {
    if ('function' !== typeof newScheduler) {
      throw new Error('newScheduler must be of type function, got: ' + typeof newScheduler);
    }
    var oldScheduler = schedule;
    schedule = newScheduler;
    return oldScheduler;
  };

  function _setTimeout(fn) {
    return setTimeout(fn);
  }

  /* istanbul ignore next */
  function _setImmediate(fn) {
    return setImmediate(fn);
  }

  function _nextTick(fn) {
    return process.nextTick(fn);
  }

  /* istanbul ignore next */
  if (typeof module !== 'undefined' && typeof module.exports !== 'undefined') {
    module.exports = callCallback;
  }
  else {
    if (typeof define === 'function' && define.amd) {
      define([], function () {
        return callCallback;
      });
    }
    else {
      window.unpromisify = callCallback;
    }
  }
})();