78 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
 | 
						|
var Promise = require('any-promise')
 | 
						|
var assert = require('assert')
 | 
						|
 | 
						|
module.exports = thenify
 | 
						|
 | 
						|
/**
 | 
						|
 * Turn async functions into promises
 | 
						|
 *
 | 
						|
 * @param {Function} fn
 | 
						|
 * @return {Function}
 | 
						|
 * @api public
 | 
						|
 */
 | 
						|
 | 
						|
function thenify(fn, options) {
 | 
						|
  assert(typeof fn === 'function')
 | 
						|
  return createWrapper(fn, options)
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
 * Turn async functions into promises and backward compatible with callback
 | 
						|
 *
 | 
						|
 * @param {Function} fn
 | 
						|
 * @return {Function}
 | 
						|
 * @api public
 | 
						|
 */
 | 
						|
 | 
						|
thenify.withCallback = function (fn, options) {
 | 
						|
  assert(typeof fn === 'function')
 | 
						|
  options = options || {}
 | 
						|
  options.withCallback = true
 | 
						|
  return createWrapper(fn, options)
 | 
						|
}
 | 
						|
 | 
						|
function createCallback(resolve, reject, multiArgs) {
 | 
						|
  // default to true
 | 
						|
  if (multiArgs === undefined) multiArgs = true
 | 
						|
  return function(err, value) {
 | 
						|
    if (err) return reject(err)
 | 
						|
    var length = arguments.length
 | 
						|
 | 
						|
    if (length <= 2 || !multiArgs) return resolve(value)
 | 
						|
 | 
						|
    if (Array.isArray(multiArgs)) {
 | 
						|
      var values = {}
 | 
						|
      for (var i = 1; i < length; i++) values[multiArgs[i - 1]] = arguments[i]
 | 
						|
      return resolve(values)
 | 
						|
    }
 | 
						|
 | 
						|
    var values = new Array(length - 1)
 | 
						|
    for (var i = 1; i < length; ++i) values[i - 1] = arguments[i]
 | 
						|
    resolve(values)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function createWrapper(fn, options) {
 | 
						|
  options = options || {}
 | 
						|
  var name = fn.name;
 | 
						|
  name = (name || '').replace(/\s|bound(?!$)/g, '')
 | 
						|
  var newFn = function () {
 | 
						|
    var self = this
 | 
						|
    var len = arguments.length
 | 
						|
    if (options.withCallback) {
 | 
						|
      var lastType = typeof arguments[len - 1]
 | 
						|
      if (lastType === 'function') return fn.apply(self, arguments)
 | 
						|
    }
 | 
						|
    var args = new Array(len + 1)
 | 
						|
    for (var i = 0; i < len; ++i) args[i] = arguments[i]
 | 
						|
    var lastIndex = i
 | 
						|
    return new Promise(function (resolve, reject) {
 | 
						|
      args[lastIndex] = createCallback(resolve, reject, options.multiArgs)
 | 
						|
      fn.apply(self, args)
 | 
						|
    })
 | 
						|
  }
 | 
						|
  Object.defineProperty(newFn, 'name', { value: name })
 | 
						|
  return newFn
 | 
						|
}
 |