twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

cancel.js (3707B)


      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             promise._setWillBeCancelled();
     34             child = promise;
     35             promise = parent;
     36         }
     37     }
     38 };
     39 
     40 Promise.prototype._branchHasCancelled = function() {
     41     this._branchesRemainingToCancel--;
     42 };
     43 
     44 Promise.prototype._enoughBranchesHaveCancelled = function() {
     45     return this._branchesRemainingToCancel === undefined ||
     46            this._branchesRemainingToCancel <= 0;
     47 };
     48 
     49 Promise.prototype._cancelBy = function(canceller) {
     50     if (canceller === this) {
     51         this._branchesRemainingToCancel = 0;
     52         this._invokeOnCancel();
     53         return true;
     54     } else {
     55         this._branchHasCancelled();
     56         if (this._enoughBranchesHaveCancelled()) {
     57             this._invokeOnCancel();
     58             return true;
     59         }
     60     }
     61     return false;
     62 };
     63 
     64 Promise.prototype._cancelBranched = function() {
     65     if (this._enoughBranchesHaveCancelled()) {
     66         this._cancel();
     67     }
     68 };
     69 
     70 Promise.prototype._cancel = function() {
     71     if (!this._isCancellable()) return;
     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.isCancellable = function() {
     89     return this.isPending() && !this.isCancelled();
     90 };
     91 
     92 Promise.prototype._doInvokeOnCancel = function(onCancelCallback, internalOnly) {
     93     if (util.isArray(onCancelCallback)) {
     94         for (var i = 0; i < onCancelCallback.length; ++i) {
     95             this._doInvokeOnCancel(onCancelCallback[i], internalOnly);
     96         }
     97     } else if (onCancelCallback !== undefined) {
     98         if (typeof onCancelCallback === "function") {
     99             if (!internalOnly) {
    100                 var e = tryCatch(onCancelCallback).call(this._boundValue());
    101                 if (e === errorObj) {
    102                     this._attachExtraTrace(e.e);
    103                     async.throwLater(e.e);
    104                 }
    105             }
    106         } else {
    107             onCancelCallback._resultCancelled(this);
    108         }
    109     }
    110 };
    111 
    112 Promise.prototype._invokeOnCancel = function() {
    113     var onCancelCallback = this._onCancel();
    114     this._unsetOnCancel();
    115     async.invoke(this._doInvokeOnCancel, this, onCancelCallback);
    116 };
    117 
    118 Promise.prototype._invokeInternalOnCancel = function() {
    119     if (this._isCancellable()) {
    120         this._doInvokeOnCancel(this._onCancel(), true);
    121         this._unsetOnCancel();
    122     }
    123 };
    124 
    125 Promise.prototype._resultCancelled = function() {
    126     this.cancel();
    127 };
    128 
    129 };