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