UNPKG

asyncc

Version:
197 lines (195 loc) 5.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = NoPromise; exports.noPromise = noPromise; /** * This is not a `Promise`. * * Chain callback functions with `.then(function (res, cb))` and execute them * as soon as previous callbacks have finished. * * Catch passed or thrown errors with `.catch(function (err, res, cb))` as they may occur. * End the chain with `.end(function (err, res))`. * * If errors are thrown inside a `task` they are catched and can be processed attaching * `.catch()` or `.end()` to the chain. * * This method is similar to {@link module:serial.connect|connect} but allows adding `tasks` on the go through chaining. * * @name NoPromise * @class * @param {Any} arg - initial argument which is passed to first chain * @example <caption>Normal usage</caption> * var arr = [] * var n = new NoPromise(arr) * n.then((res, cb) => { * res.push(1) * cb(null, res) * }).then((res, cb) => { * res.push(2) * cb(null, res) * }).end((err, res) => { * //> err = null * //> res = [1, 2] * //> (arr ==== res) = true * }) * @example <caption>Catch errors</caption> * var arr = [] * var n = new NoPromise(arr) * n.then((res, cb) => { * res.push(1) * cb(null, res) * }).then((res, cb) => { * res.push(2) * cb('err1', res) // <-- cause an error * }).catch((err, res, cb) => { // catches err1 * res.push(err) * cb(null, res) // <-- continue normally * }).then((res, cb) => { * res.push(3) * cb(null, res) * }).catch((err, res, cb) => { // jumps over, as there is no error in the chain * res.push(4) * cb(null, res) * }).then((res, cb) => { * res.push(5) * cb('err2', res) // <-- next error * }).end((err, res) => { * //> err = 'err2' * //> res = [1, 2, 'err1', 3, 5] * //> (arr ==== res) = true * }) * @example <caption>Deferred usage</caption> * var arr = [] * // creates a new instance passing `arr` * var n = new NoPromise(arr) * // execute the first async method * n.then((res, cb) => { * res.push(1) * cb(null, res) * }) * // take a time off * setTimeout(() => { * // continue processing * n.then((res, cb) => { * res.push(2) * cb(null, res) * }).end((err, res) => { * //> err = null * //> res = [1, 2] * //> (arr ==== res) = true * }) * }, 10) */ function NoPromise(arg) { this._tasks = []; this.result = arg; this.error = undefined; this._lock = false; } NoPromise.prototype = { /** * runs the next function * @private */ _run: function _run() { var _this = this; if (this._lock) return; this._lock = true; var task = this._tasks.shift(); var tstType = this.error ? ['catch', 'end'] : ['then', 'end']; while (task && !~tstType.indexOf(task.type)) { task = this._tasks.shift(); } if (task) { var cb = function cb(err, res) { _this.error = err; _this.result = res || _this.result; _this._lock = false; _this._run(); }; var fn = task.fn; if (task.type === 'end') { // .end fn(this.error, this.result); } else { try { if (task.type === 'catch') { // .catch fn(this.error, this.result, cb); } else { // .then fn(this.result, cb); } } catch (e) { cb(e); } } } else { this._lock = false; } }, /** * Chain the next async function * @param {Function} task - async function `function (res: any, cb: Function)`. * Never forget to call `cb(err: <Error>, res: any)` inside `fn` */ then: function then(task) { this._tasks.push({ type: 'then', fn: task }); this._run(); return this; }, /** * Catch any previous errors from the chain * @param {Function} trap - async function `function (err: <Error>, res: any, cb: Function)`. * Never forget to call `cb(err: <Error>, res: any)` inside `fn` */ "catch": function _catch(trap) { this._tasks.push({ type: 'catch', fn: trap }); this._run(); return this; }, /** * End the chain * @param {Function} callback - `function (err: <Error>, res: any)` */ end: function end(callback) { this._tasks.push({ type: 'end', fn: callback }); this._run(); } }; /** * This is not a `Promise`. * * Chain callback functions with `.then(function (res, cb))` and execute them * as soon as previous callbacks have finished. * * Catch passed or thrown errors with `.catch(function (err, res, cb))` as they may occur. * End the chain with `.end(function (err, res))`. * * If errors are thrown inside a `task` they are catched and can be processed attaching * `.catch()` or `.end()` to the chain. * * See full API here {@link NoPromise}. * * @name noPromise * @memberOf module:serial * @static * @method * @param {Any} arg - initial argument which is passed to first chain * @return {NoPromise} */ function noPromise(arg) { return new NoPromise(arg); }