1'use strict'; 2 3const ObjectGetOwnPropertyDescriptors = require('object.getownpropertydescriptors'); 4const util = require('util'); 5const timers = require('timers'); 6 7const kCustomPromisifiedSymbol = util.promisify && util.promisify.custom || Symbol('util.promisify.custom'); 8//const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs'); 9 10function promisify(orig) { 11 if (typeof orig !== 'function') { 12 //const errors = require('internal/errors'); 13 //throw new errors.TypeError('ERR_INVALID_ARG_TYPE', 'original', 'function'); 14 var err = TypeError(`The "original" argument must be of type function`); 15 err.code = 'ERR_INVALID_ARG_TYPE'; 16 err.name = `TypeError [${err.code}]`; 17 throw err 18 } 19 20 if (orig === timers.setTimeout || orig === timers.setImmediate) { 21 const _orig = orig 22 orig = function () { 23 var args = []; 24 for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]); 25 const _cb = args.pop() 26 const cb = function () { 27 var args = []; 28 for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]); 29 _cb.apply(null, [null].concat(args)) 30 } 31 _orig.apply(timers, [cb].concat(args)) 32 } 33 } 34 35 if (orig[kCustomPromisifiedSymbol]) { 36 const fn = orig[kCustomPromisifiedSymbol]; 37 if (typeof fn !== 'function') { 38 throw new TypeError('The [util.promisify.custom] property must be ' + 39 'a function'); 40 } 41 Object.defineProperty(fn, kCustomPromisifiedSymbol, { 42 value: fn, enumerable: false, writable: false, configurable: true 43 }); 44 return fn; 45 } 46 47 // Names to create an object from in case the callback receives multiple 48 // arguments, e.g. ['stdout', 'stderr'] for child_process.exec. 49 //const argumentNames = orig[kCustomPromisifyArgsSymbol]; 50 51 function fn() { 52 var args = []; 53 for (var i = 0; i < arguments.length; i ++) args.push(arguments[i]); 54 55 let resolve, reject; 56 const promise = new Promise(function (_resolve, _reject) { 57 resolve = _resolve; 58 reject = _reject; 59 }); 60 try { 61 orig.apply(this, args.concat(function (err) { 62 var values = []; 63 for (var i = 1; i < arguments.length; i++) values.push(arguments[i]); 64 if (err) { 65 reject(err); 66 //} else if (argumentNames !== undefined && values.length > 1) { 67 // const obj = {}; 68 // for (var i = 0; i < argumentNames.length; i++) 69 // obj[argumentNames[i]] = values[i]; 70 // resolve(obj); 71 } else { 72 resolve(values[0]); 73 } 74 })); 75 } catch (err) { 76 reject(err); 77 } 78 return promise; 79 } 80 81 Object.setPrototypeOf(fn, Object.getPrototypeOf(orig)); 82 83 Object.defineProperty(fn, kCustomPromisifiedSymbol, { 84 value: fn, enumerable: false, writable: false, configurable: true 85 }); 86 return Object.defineProperties(fn, ObjectGetOwnPropertyDescriptors(orig)); 87} 88 89promisify.custom = kCustomPromisifiedSymbol; 90 91module.exports = promisify; 92