| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | "use strict";module.exports = function(Promise, tryConvertToPromise, NEXT_FILTER) {var util = require("./util");var CancellationError = Promise.CancellationError;var errorObj = util.errorObj;var catchFilter = require("./catch_filter")(NEXT_FILTER);function PassThroughHandlerContext(promise, type, handler) {    this.promise = promise;    this.type = type;    this.handler = handler;    this.called = false;    this.cancelPromise = null;}PassThroughHandlerContext.prototype.isFinallyHandler = function() {    return this.type === 0;};function FinallyHandlerCancelReaction(finallyHandler) {    this.finallyHandler = finallyHandler;}FinallyHandlerCancelReaction.prototype._resultCancelled = function() {    checkCancel(this.finallyHandler);};function checkCancel(ctx, reason) {    if (ctx.cancelPromise != null) {        if (arguments.length > 1) {            ctx.cancelPromise._reject(reason);        } else {            ctx.cancelPromise._cancel();        }        ctx.cancelPromise = null;        return true;    }    return false;}function succeed() {    return finallyHandler.call(this, this.promise._target()._settledValue());}function fail(reason) {    if (checkCancel(this, reason)) return;    errorObj.e = reason;    return errorObj;}function finallyHandler(reasonOrValue) {    var promise = this.promise;    var handler = this.handler;    if (!this.called) {        this.called = true;        var ret = this.isFinallyHandler()            ? handler.call(promise._boundValue())            : handler.call(promise._boundValue(), reasonOrValue);        if (ret === NEXT_FILTER) {            return ret;        } else if (ret !== undefined) {            promise._setReturnedNonUndefined();            var maybePromise = tryConvertToPromise(ret, promise);            if (maybePromise instanceof Promise) {                if (this.cancelPromise != null) {                    if (maybePromise._isCancelled()) {                        var reason =                            new CancellationError("late cancellation observer");                        promise._attachExtraTrace(reason);                        errorObj.e = reason;                        return errorObj;                    } else if (maybePromise.isPending()) {                        maybePromise._attachCancellationCallback(                            new FinallyHandlerCancelReaction(this));                    }                }                return maybePromise._then(                    succeed, fail, undefined, this, undefined);            }        }    }    if (promise.isRejected()) {        checkCancel(this);        errorObj.e = reasonOrValue;        return errorObj;    } else {        checkCancel(this);        return reasonOrValue;    }}Promise.prototype._passThrough = function(handler, type, success, fail) {    if (typeof handler !== "function") return this.then();    return this._then(success,                      fail,                      undefined,                      new PassThroughHandlerContext(this, type, handler),                      undefined);};Promise.prototype.lastly =Promise.prototype["finally"] = function (handler) {    return this._passThrough(handler,                             0,                             finallyHandler,                             finallyHandler);};Promise.prototype.tap = function (handler) {    return this._passThrough(handler, 1, finallyHandler);};Promise.prototype.tapCatch = function (handlerOrPredicate) {    var len = arguments.length;    if(len === 1) {        return this._passThrough(handlerOrPredicate,                                 1,                                 undefined,                                 finallyHandler);    } else {         var catchInstances = new Array(len - 1),            j = 0, i;        for (i = 0; i < len - 1; ++i) {            var item = arguments[i];            if (util.isObject(item)) {                catchInstances[j++] = item;            } else {                return Promise.reject(new TypeError(                    "tapCatch statement predicate: "                    + "expecting an object but got " + util.classString(item)                ));            }        }        catchInstances.length = j;        var handler = arguments[i];        return this._passThrough(catchFilter(catchInstances, handler, this),                                 1,                                 undefined,                                 finallyHandler);    }};return PassThroughHandlerContext;};
 |