UNPKG

reflux-promise

Version:

Extension to reflux-core to use Promises.

147 lines (121 loc) 4.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function createFunctions(Reflux, PromiseFactory) { var _ = Reflux.utils; /** * Returns a Promise for the triggered action * * @return {Promise} * Resolved by completed child action. * Rejected by failed child action. * If listenAndPromise'd, then promise associated to this trigger. * Otherwise, the promise is for next child action completion. */ function triggerPromise() { var me = this; var args = arguments; var canHandlePromise = this.children.indexOf("completed") >= 0 && this.children.indexOf("failed") >= 0; var createdPromise = new PromiseFactory(function (resolve, reject) { // If `listenAndPromise` is listening // patch `promise` w/ context-loaded resolve/reject if (me.willCallPromise) { _.nextTick(function () { var previousPromise = me.promise; me.promise = function (inputPromise) { inputPromise.then(resolve, reject); // Back to your regularly schedule programming. me.promise = previousPromise; return me.promise.apply(me, arguments); }; me.trigger.apply(me, args); }); return; } if (canHandlePromise) { var removeSuccess = me.completed.listen(function () { var args = Array.prototype.slice.call(arguments); removeSuccess(); removeFailed(); resolve(args.length > 1 ? args : args[0]); }); var removeFailed = me.failed.listen(function () { var args = Array.prototype.slice.call(arguments); removeSuccess(); removeFailed(); reject(args.length > 1 ? args : args[0]); }); } me.trigger.apply(me, args); if (!canHandlePromise) { resolve(); } }); // Ensure that the promise does trigger "Uncaught (in promise)" errors in console if no error handler is added // See: https://github.com/reflux/reflux-promise/issues/4 createdPromise["catch"](function () {}); return createdPromise; } /** * Attach handlers to promise that trigger the completed and failed * child publishers, if available. * * @param {Object} p The promise to attach to */ function promise(p) { var me = this; var canHandlePromise = this.children.indexOf("completed") >= 0 && this.children.indexOf("failed") >= 0; if (!canHandlePromise) { throw new Error("Publisher must have \"completed\" and \"failed\" child publishers"); } p.then(function (response) { return me.completed(response); }, function (error) { return me.failed(error); }); } /** * Subscribes the given callback for action triggered, which should * return a promise that in turn is passed to `this.promise` * * @param {Function} callback The callback to register as event handler */ function listenAndPromise(callback, bindContext) { var me = this; bindContext = bindContext || this; this.willCallPromise = (this.willCallPromise || 0) + 1; var removeListen = this.listen(function () { if (!callback) { throw new Error("Expected a function returning a promise but got " + callback); } var args = arguments, returnedPromise = callback.apply(bindContext, args); return me.promise.call(me, returnedPromise); }, bindContext); return function () { me.willCallPromise--; removeListen.call(me); }; } return { triggerPromise: triggerPromise, promise: promise, listenAndPromise: listenAndPromise }; } /** * Sets up reflux with Promise functionality */ exports["default"] = function (promiseFactory) { return function (Reflux) { var _createFunctions = createFunctions(Reflux, promiseFactory); var triggerPromise = _createFunctions.triggerPromise; var promise = _createFunctions.promise; var listenAndPromise = _createFunctions.listenAndPromise; Reflux.PublisherMethods.triggerAsync = triggerPromise; Reflux.PublisherMethods.promise = promise; Reflux.PublisherMethods.listenAndPromise = listenAndPromise; }; }; module.exports = exports["default"];