100 lines
2.6 KiB
JavaScript
100 lines
2.6 KiB
JavaScript
|
"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);
|
||
|
};
|
||
|
};
|