Version 1
[yaffs-website] / node_modules / bluebird / js / release / cancel.js
1 "use strict";
2 module.exports = function(Promise, PromiseArray, apiRejection, debug) {
3 var util = require("./util");
4 var tryCatch = util.tryCatch;
5 var errorObj = util.errorObj;
6 var async = Promise._async;
7
8 Promise.prototype["break"] = Promise.prototype.cancel = function() {
9     if (!debug.cancellation()) return this._warn("cancellation is disabled");
10
11     var promise = this;
12     var child = promise;
13     while (promise.isCancellable()) {
14         if (!promise._cancelBy(child)) {
15             if (child._isFollowing()) {
16                 child._followee().cancel();
17             } else {
18                 child._cancelBranched();
19             }
20             break;
21         }
22
23         var parent = promise._cancellationParent;
24         if (parent == null || !parent.isCancellable()) {
25             if (promise._isFollowing()) {
26                 promise._followee().cancel();
27             } else {
28                 promise._cancelBranched();
29             }
30             break;
31         } else {
32             if (promise._isFollowing()) promise._followee().cancel();
33             child = promise;
34             promise = parent;
35         }
36     }
37 };
38
39 Promise.prototype._branchHasCancelled = function() {
40     this._branchesRemainingToCancel--;
41 };
42
43 Promise.prototype._enoughBranchesHaveCancelled = function() {
44     return this._branchesRemainingToCancel === undefined ||
45            this._branchesRemainingToCancel <= 0;
46 };
47
48 Promise.prototype._cancelBy = function(canceller) {
49     if (canceller === this) {
50         this._branchesRemainingToCancel = 0;
51         this._invokeOnCancel();
52         return true;
53     } else {
54         this._branchHasCancelled();
55         if (this._enoughBranchesHaveCancelled()) {
56             this._invokeOnCancel();
57             return true;
58         }
59     }
60     return false;
61 };
62
63 Promise.prototype._cancelBranched = function() {
64     if (this._enoughBranchesHaveCancelled()) {
65         this._cancel();
66     }
67 };
68
69 Promise.prototype._cancel = function() {
70     if (!this.isCancellable()) return;
71
72     this._setCancelled();
73     async.invoke(this._cancelPromises, this, undefined);
74 };
75
76 Promise.prototype._cancelPromises = function() {
77     if (this._length() > 0) this._settlePromises();
78 };
79
80 Promise.prototype._unsetOnCancel = function() {
81     this._onCancelField = undefined;
82 };
83
84 Promise.prototype.isCancellable = function() {
85     return this.isPending() && !this.isCancelled();
86 };
87
88 Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) {
89     if (util.isArray(onCancelCallback)) {
90         for (var i = 0; i < onCancelCallback.length; ++i) {
91             this._doInvokeOnCancel(onCancelCallback[i], internalOnly);
92         }
93     } else if (onCancelCallback !== undefined) {
94         if (typeof onCancelCallback === "function") {
95             if (!internalOnly) {
96                 var e = tryCatch(onCancelCallback).call(this._boundValue());
97                 if (e === errorObj) {
98                     this._attachExtraTrace(e.e);
99                     async.throwLater(e.e);
100                 }
101             }
102         } else {
103             onCancelCallback._resultCancelled(this);
104         }
105     }
106 };
107
108 Promise.prototype._invokeOnCancel = function() {
109     var onCancelCallback = this._onCancel();
110     this._unsetOnCancel();
111     async.invoke(this._doInvokeOnCancel, this, onCancelCallback);
112 };
113
114 Promise.prototype._invokeInternalOnCancel = function() {
115     if (this.isCancellable()) {
116         this._doInvokeOnCancel(this._onCancel(), true);
117         this._unsetOnCancel();
118     }
119 };
120
121 Promise.prototype._resultCancelled = function() {
122     this.cancel();
123 };
124
125 };