Version 1
[yaffs-website] / node_modules / bluebird / js / release / finally.js
1 "use strict";
2 module.exports = function(Promise, tryConvertToPromise) {
3 var util = require("./util");
4 var CancellationError = Promise.CancellationError;
5 var errorObj = util.errorObj;
6
7 function PassThroughHandlerContext(promise, type, handler) {
8     this.promise = promise;
9     this.type = type;
10     this.handler = handler;
11     this.called = false;
12     this.cancelPromise = null;
13 }
14
15 function FinallyHandlerCancelReaction(finallyHandler) {
16     this.finallyHandler = finallyHandler;
17 }
18
19 FinallyHandlerCancelReaction.prototype._resultCancelled = function() {
20     checkCancel(this.finallyHandler);
21 };
22
23 function checkCancel(ctx, reason) {
24     if (ctx.cancelPromise != null) {
25         if (arguments.length > 1) {
26             ctx.cancelPromise._reject(reason);
27         } else {
28             ctx.cancelPromise._cancel();
29         }
30         ctx.cancelPromise = null;
31         return true;
32     }
33     return false;
34 }
35
36 function succeed() {
37     return finallyHandler.call(this, this.promise._target()._settledValue());
38 }
39 function fail(reason) {
40     if (checkCancel(this, reason)) return;
41     errorObj.e = reason;
42     return errorObj;
43 }
44 function finallyHandler(reasonOrValue) {
45     var promise = this.promise;
46     var handler = this.handler;
47
48     if (!this.called) {
49         this.called = true;
50         var ret = this.type === 0
51             ? handler.call(promise._boundValue())
52             : handler.call(promise._boundValue(), reasonOrValue);
53         if (ret !== undefined) {
54             promise._setReturnedNonUndefined();
55             var maybePromise = tryConvertToPromise(ret, promise);
56             if (maybePromise instanceof Promise) {
57                 if (this.cancelPromise != null) {
58                     if (maybePromise.isCancelled()) {
59                         var reason =
60                             new CancellationError("late cancellation observer");
61                         promise._attachExtraTrace(reason);
62                         errorObj.e = reason;
63                         return errorObj;
64                     } else if (maybePromise.isPending()) {
65                         maybePromise._attachCancellationCallback(
66                             new FinallyHandlerCancelReaction(this));
67                     }
68                 }
69                 return maybePromise._then(
70                     succeed, fail, undefined, this, undefined);
71             }
72         }
73     }
74
75     if (promise.isRejected()) {
76         checkCancel(this);
77         errorObj.e = reasonOrValue;
78         return errorObj;
79     } else {
80         checkCancel(this);
81         return reasonOrValue;
82     }
83 }
84
85 Promise.prototype._passThrough = function(handler, type, success, fail) {
86     if (typeof handler !== "function") return this.then();
87     return this._then(success,
88                       fail,
89                       undefined,
90                       new PassThroughHandlerContext(this, type, handler),
91                       undefined);
92 };
93
94 Promise.prototype.lastly =
95 Promise.prototype["finally"] = function (handler) {
96     return this._passThrough(handler,
97                              0,
98                              finallyHandler,
99                              finallyHandler);
100 };
101
102 Promise.prototype.tap = function (handler) {
103     return this._passThrough(handler, 1, finallyHandler);
104 };
105
106 return PassThroughHandlerContext;
107 };