UNPKG

staggerjs

Version:

Light utility to stagger a stack of async methods

48 lines (36 loc) 1.25 kB
import t from 'tcomb'; import _throttle from 'throttle-function'; const InfinityType = t.irreducible('InfinityType', x => typeof x === 'number' && x === Infinity); const Methods = t.list(t.Function); const Settings = t.interface({ perSecond: t.union([t.Number, InfinityType]), maxOngoingMethods: t.union([t.Integer, InfinityType]) }, { strict: true }); const defaultSettings = { perSecond: 20, maxOngoingMethods: 5 }; export default (_methods, _settings) => { const methods = Methods(_methods); const settings = Settings({ ...defaultSettings, ..._settings }); const { maxOngoingMethods, perSecond } = settings; const throttle = _throttle(method => method(), { window: 1, // window is in seconds limit: perSecond }); return new Promise((resolve) => { const queue = []; const onDone = res => { throttle(() => runMethod(methods[queue.length])); return res; }; const runMethod = method => { if (queue.length !== methods.length) { queue.push(method().then(onDone).catch(onDone)); } else { resolve(Promise.all(queue)); } }; methods.slice(0, maxOngoingMethods).forEach((m, i) => i === 0 ? runMethod(m) : throttle(() => runMethod(m))); }); };