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.
		
		
		
		
		
			
		
			
				
					147 lines
				
				4.5 KiB
			
		
		
			
		
	
	
					147 lines
				
				4.5 KiB
			| 
											3 years ago
										 | "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; | ||
|  | }; |