You've already forked Epicnabbo-Catalogus-Updated-Daily
178 lines
4.0 KiB
JavaScript
178 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
const Aigle = require('./aigle');
|
|
const { INTERNAL, callThen } = require('./internal/util');
|
|
|
|
const globalSetImmediate = typeof setImmediate === 'function' ? setImmediate : {};
|
|
const custom =
|
|
(() => {
|
|
try {
|
|
return require('util').promisify.custom;
|
|
} catch (e) {
|
|
return;
|
|
}
|
|
})() || {};
|
|
|
|
module.exports = promisify;
|
|
|
|
/**
|
|
* @param {Object|Function} fn
|
|
* @param {string|number|Object} [fn]
|
|
* @param {Object} [fn.context]
|
|
* @example
|
|
* const func = (a, b, c, callback) => callback(null, a + b + c);
|
|
* Aigle.promisify(func)(1, 2, 3)
|
|
* .then(value => console.log(value)); // 6
|
|
*
|
|
* @example
|
|
* const obj = {
|
|
* val: 1,
|
|
* get(callback) {
|
|
* callback(null, this.val);
|
|
* }
|
|
* };
|
|
*
|
|
* // using bind
|
|
* Aigle.promisify(obj.get.bind(obj))().then(console.log);
|
|
*
|
|
* // using context
|
|
* Aigle.promisify(obj.get, { context: obj })().then(console.log);
|
|
*
|
|
* // using shorthand
|
|
* Aigle.promisify(obj, 'get')().then(console.log);
|
|
*/
|
|
function promisify(fn, opts) {
|
|
switch (typeof fn) {
|
|
case 'object':
|
|
switch (typeof opts) {
|
|
case 'string':
|
|
case 'number':
|
|
if (typeof fn[opts] !== 'function') {
|
|
throw new TypeError('Function not found key: ' + opts);
|
|
}
|
|
if (fn[opts].__isPromisified__) {
|
|
return fn[opts];
|
|
}
|
|
return makeFunctionByKey(fn, opts);
|
|
default:
|
|
throw new TypeError('Second argument is invalid');
|
|
}
|
|
case 'function':
|
|
if (fn.__isPromisified__) {
|
|
return fn;
|
|
}
|
|
const ctx = opts && opts.context !== undefined ? opts.context : undefined;
|
|
return makeFunction(fn, ctx);
|
|
default:
|
|
throw new TypeError('Type of first argument is not function');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @param {Aigle} promise
|
|
*/
|
|
function makeCallback(promise) {
|
|
return (err, res) => (err ? promise._reject(err) : promise._resolve(res));
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @param {Object} obj
|
|
* @param {string} key
|
|
*/
|
|
function makeFunctionByKey(obj, key) {
|
|
promisified.__isPromisified__ = true;
|
|
return promisified;
|
|
|
|
function promisified(arg) {
|
|
const promise = new Aigle(INTERNAL);
|
|
const callback = makeCallback(promise);
|
|
let l = arguments.length;
|
|
switch (l) {
|
|
case 0:
|
|
obj[key](callback);
|
|
break;
|
|
case 1:
|
|
obj[key](arg, callback);
|
|
break;
|
|
default:
|
|
const args = Array(l);
|
|
while (l--) {
|
|
args[l] = arguments[l];
|
|
}
|
|
args[args.length] = callback;
|
|
obj[key].apply(obj, args);
|
|
break;
|
|
}
|
|
return promise;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* @param {function} fn
|
|
* @param {*} [ctx]
|
|
*/
|
|
function makeFunction(fn, ctx) {
|
|
const func = fn[custom];
|
|
if (func) {
|
|
nativePromisified.__isPromisified__ = true;
|
|
return nativePromisified;
|
|
}
|
|
switch (fn) {
|
|
case setTimeout:
|
|
return Aigle.delay;
|
|
case globalSetImmediate:
|
|
return Aigle.resolve;
|
|
}
|
|
promisified.__isPromisified__ = true;
|
|
return promisified;
|
|
|
|
function nativePromisified(arg) {
|
|
const promise = new Aigle(INTERNAL);
|
|
let l = arguments.length;
|
|
let p;
|
|
switch (l) {
|
|
case 0:
|
|
p = func.call(ctx || this);
|
|
break;
|
|
case 1:
|
|
p = func.call(ctx || this, arg);
|
|
break;
|
|
default:
|
|
const args = Array(l);
|
|
while (l--) {
|
|
args[l] = arguments[l];
|
|
}
|
|
p = func.apply(ctx || this, args);
|
|
break;
|
|
}
|
|
callThen(p, promise);
|
|
return promise;
|
|
}
|
|
|
|
function promisified(arg) {
|
|
const promise = new Aigle(INTERNAL);
|
|
const callback = makeCallback(promise);
|
|
let l = arguments.length;
|
|
switch (l) {
|
|
case 0:
|
|
fn.call(ctx || this, callback);
|
|
break;
|
|
case 1:
|
|
fn.call(ctx || this, arg, callback);
|
|
break;
|
|
default:
|
|
const args = Array(l);
|
|
while (l--) {
|
|
args[l] = arguments[l];
|
|
}
|
|
args[args.length] = callback;
|
|
fn.apply(ctx || this, args);
|
|
break;
|
|
}
|
|
return promise;
|
|
}
|
|
}
|