function forEachSerial(array, func) { var tickFunction = function (el, index, callback) { if (func.length == 2) func(el, callback); else if (func.length == 3) func(el, index, callback); } var functions = []; array.forEach(function (el, index) { functions.push(Q.nfcall(tickFunction, el, index)); }); return Q.all(functions); }
function documentToJSON(el, options) { var obj = el.toObject(options); var deferred = Q.defer(); var columns = ['...','...','...']; forEachSerial(columns,function (el, next) { el.somyAsyncFunction(options, function (err, result) { if (err) next(err); else result.somyAsyncFunction2(options, function (err, result) { if (!err) obj[el] = result; next(err); }); }); }).then(function () { deferred.resolve(obj); }, function (err) { deferred.reject(err); }); return deferred.promise; }
exports.get = function (req, res, next) { dbModel.find(search, {}, { skip: from, limit: limit }).sort({column1: -1}).exec(function (err, result) { if (err) next(new errorsHandlers.internalError()); else { var result = []; forEachSerial(result,function (el, index, next) { documentToJSON(el,options).then(function (obj) { result[index] = obj; next() }, function (err) { next(new errorsHandlers.internalError()) }); }).then(function () { res.send({responce: result}); }, function (err) { next(new errorsHandlers.internalError()) }); } }); };
Promise.then(step1).then(step2).then(step3).then(function () { //All OK }, function (err) { //Error in any step });
var promise = fs.stat("foo"); promise.addListener("success", function (value) { // ok }) promise.addListener("error", function (error) { // error });
function deferred() { this.events = new EventEmitter(); // this.promise = new promise(this); // Promise this.thenDeferred = []; // , var self = this; // this.resolve = function () { self.events.emit('completed', arguments); } // this.reject = function (error) { self.events.emit('error', error); // self.thenDeferred.forEach(function (el) { el.reject(error); }); } }
function promise(def) { this.def = def; this.completed = false; this.events = def.events; var self = this; var thenDeferred; self._successListener = null; self._errorListener = null; // then - promise this.then = function (success, error) { if (success) self._successListener = success; if (error) self._errorListener = error; thenDeferred = new deferred(); self.def.thenDeferred.push(thenDeferred); return thenDeferred.promise; } // this.events.on('completed', function (result) { // , , var args = inputOfFunctionToArray(result); // , if (self.completed) return; self.completed = true; if (self._successListener) { var result; try { result = self._successListener.apply(self, args); } catch (e) { self.def.reject(e); result; } // Promise then, var promise; if (isPromise(result)) promise = result; else if (result instanceof deferred) promise = result.promise; if (promise && thenDeferred) { promise.then(function () { var args = arguments; process.nextTick(function () { thenDeferred.resolve.apply(self, args); }); }, function (error) { process.nextTick(function () { thenDeferred.reject(error); }); }); } else if (thenDeferred) process.nextTick(function () { // then thenDeferred.resolve.apply(self, [result]); }); } else if (thenDeferred) process.nextTick(function () { thenDeferred.resolve.apply(self, []); }); }); // this.events.on('error', function (error) { if (self.completed) return; self.completed = true; if (self._errorListener) process.nextTick(function () { self._errorListener.apply(self, [error]); }); }); }
var promisefn = function (bind, fn) { var def = new deferred(); //bind if (typeof bind === 'function' && !fn) { fn = bind; bind = def; } // callback var callback = function (err) { if (err) def.reject(err); else { var args = []; for (var key in arguments) args.push(arguments[key]); args.splice(0, 1); def.resolve.apply(bind, args); } }; var result = function () { var args = []; for (var key in arguments) args.push(arguments[key]); args.push(callback); process.nextTick(function () { fn.apply(bind, args); }); return def.promise; } return result; }
var all = function (functions) { var def = new deferred(); process.nextTick(function () { var index = -1; var result = []; var next = function (err, arguments) { if (err) { def.reject(err); return; } if (arguments) result.push(inputOfFunctionToArray(arguments)); index++; if (index >= functions.length) { def.resolve(result); } else process.nextTick(function () { promisefn(functions[index])().then(function () { var args = arguments; process.nextTick(function () { next(err, args); }); }, function (err) { process.nextTick(function () { next(err); }); }); }); } process.nextTick(next); }); return def.promise; }
Source: https://habr.com/ru/post/168929/
All Articles