You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							111 lines
						
					
					
						
							3.3 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							111 lines
						
					
					
						
							3.3 KiB
						
					
					
				
								"use strict";
							 | 
						|
								module.exports = function(Promise, tryConvertToPromise) {
							 | 
						|
								var util = require("./util");
							 | 
						|
								var CancellationError = Promise.CancellationError;
							 | 
						|
								var errorObj = util.errorObj;
							 | 
						|
								
							 | 
						|
								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 !== 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);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								return PassThroughHandlerContext;
							 | 
						|
								};
							 | 
						|
								
							 |