| "use strict"; |
| module.exports = asPromise; |
| |
| /** |
| * Callback as used by {@link util.asPromise}. |
| * @typedef asPromiseCallback |
| * @type {function} |
| * @param {Error|null} error Error, if any |
| * @param {...*} params Additional arguments |
| * @returns {undefined} |
| */ |
| |
| /** |
| * Returns a promise from a node-style callback function. |
| * @memberof util |
| * @param {asPromiseCallback} fn Function to call |
| * @param {*} ctx Function context |
| * @param {...*} params Function arguments |
| * @returns {Promise<*>} Promisified function |
| */ |
| function asPromise(fn, ctx/*, varargs */) { |
| var params = new Array(arguments.length - 1), |
| offset = 0, |
| index = 2, |
| pending = true; |
| while (index < arguments.length) |
| params[offset++] = arguments[index++]; |
| return new Promise(function executor(resolve, reject) { |
| params[offset] = function callback(err/*, varargs */) { |
| if (pending) { |
| pending = false; |
| if (err) |
| reject(err); |
| else { |
| var params = new Array(arguments.length - 1), |
| offset = 0; |
| while (offset < params.length) |
| params[offset++] = arguments[offset]; |
| resolve.apply(null, params); |
| } |
| } |
| }; |
| try { |
| fn.apply(ctx || null, params); |
| } catch (err) { |
| if (pending) { |
| pending = false; |
| reject(err); |
| } |
| } |
| }); |
| } |