| "use strict"; |
| module.exports = function(Promise, NEXT_FILTER, tryConvertToPromise) { |
| var util = require("./util.js"); |
| var wrapsPrimitiveReceiver = util.wrapsPrimitiveReceiver; |
| var isPrimitive = util.isPrimitive; |
| var thrower = util.thrower; |
| |
| function returnThis() { |
| return this; |
| } |
| function throwThis() { |
| throw this; |
| } |
| function return$(r) { |
| return function() { |
| return r; |
| }; |
| } |
| function throw$(r) { |
| return function() { |
| throw r; |
| }; |
| } |
| function promisedFinally(ret, reasonOrValue, isFulfilled) { |
| var then; |
| if (wrapsPrimitiveReceiver && isPrimitive(reasonOrValue)) { |
| then = isFulfilled ? return$(reasonOrValue) : throw$(reasonOrValue); |
| } else { |
| then = isFulfilled ? returnThis : throwThis; |
| } |
| return ret._then(then, thrower, undefined, reasonOrValue, undefined); |
| } |
| |
| function finallyHandler(reasonOrValue) { |
| var promise = this.promise; |
| var handler = this.handler; |
| |
| var ret = promise._isBound() |
| ? handler.call(promise._boundTo) |
| : handler(); |
| |
| if (ret !== undefined) { |
| var maybePromise = tryConvertToPromise(ret, promise); |
| if (maybePromise instanceof Promise) { |
| maybePromise = maybePromise._target(); |
| return promisedFinally(maybePromise, reasonOrValue, |
| promise.isFulfilled()); |
| } |
| } |
| |
| if (promise.isRejected()) { |
| NEXT_FILTER.e = reasonOrValue; |
| return NEXT_FILTER; |
| } else { |
| return reasonOrValue; |
| } |
| } |
| |
| function tapHandler(value) { |
| var promise = this.promise; |
| var handler = this.handler; |
| |
| var ret = promise._isBound() |
| ? handler.call(promise._boundTo, value) |
| : handler(value); |
| |
| if (ret !== undefined) { |
| var maybePromise = tryConvertToPromise(ret, promise); |
| if (maybePromise instanceof Promise) { |
| maybePromise = maybePromise._target(); |
| return promisedFinally(maybePromise, value, true); |
| } |
| } |
| return value; |
| } |
| |
| Promise.prototype._passThroughHandler = function (handler, isFinally) { |
| if (typeof handler !== "function") return this.then(); |
| |
| var promiseAndHandler = { |
| promise: this, |
| handler: handler |
| }; |
| |
| return this._then( |
| isFinally ? finallyHandler : tapHandler, |
| isFinally ? finallyHandler : undefined, undefined, |
| promiseAndHandler, undefined); |
| }; |
| |
| Promise.prototype.lastly = |
| Promise.prototype["finally"] = function (handler) { |
| return this._passThroughHandler(handler, true); |
| }; |
| |
| Promise.prototype.tap = function (handler) { |
| return this._passThroughHandler(handler, false); |
| }; |
| }; |