UNPKG

putil-promisify

Version:

Simple and lightweight utility for transforming callback functions to Promises

100 lines (88 loc) 2.34 kB
/* putil-promisify ------------------------ (c) 2017-present Panates https://panates.github.io/putil-promisify/ */ const promisify = function(fn) { if (promisify.isPromise(fn)) return fn; if (typeof fn !== 'function') return Promise.resolve(fn); return new Promise((resolve, reject) => { try { const o = fn(); if (promisify.isPromise(o)) { o.then(v => resolve(v)) .catch((e) => reject(e)); } else resolve(o); } catch (e) { reject(e); } }); }; promisify.fromCallback = function(resolver) { return new Promise((resolve, reject) => { try { resolver((error, value) => { if (error) reject(error); else resolve(value); }); } catch (e) { reject(e); } }); }; promisify.isPromise = function(o) { return o && (o instanceof global.Promise || o instanceof Promise || (typeof o === 'object' && typeof o.then === 'function' && typeof o.catch === 'function')); }; promisify.deepResolve = function(obj) { if (obj instanceof Promise) return Promise.resolve(obj) .then(v => promisify.deepResolve(v)); const stackSet = new Set(); const promises = []; const visitObj = (v) => { if (v && typeof v === 'object') { if (stackSet.has(v)) return; stackSet.add(v); } if (Array.isArray(v)) { const len = v.length; for (let i = 0; i < len; i++) { if (v[i] instanceof Promise) { promises.push(v[i].then((x) => v[i] = x)); } else visitObj(v[i]); } } else if (v && typeof v === 'object') { for (const k of Object.keys(v)) { if (v[k] instanceof Promise) { promises.push(v[k].then((x) => v[k] = x)); } else visitObj(v[k]); } } }; visitObj(obj); return promises.length ? Promise.all(promises).then( () => promisify.deepResolve(obj)) : obj; }; promisify.wait = function(ms) { return new Promise((resolve) => { setTimeout(resolve, ms); }); }; promisify.await = function(x, callback) { if (promisify.isPromise(x)) return x.then((v) => callback && callback(undefined, v)) .catch((e) => callback && callback(e)); else callback && callback(undefined, x); }; module.exports = promisify;