-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Allow
Pledge
instances to be cancelled
- Loading branch information
Showing
3 changed files
with
301 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,18 @@ | ||
const PENDING = 0, | ||
RESOLVED = 1, | ||
REJECTED = 2; | ||
REJECTED = 2, | ||
CANCELLED = 3; | ||
|
||
const REJECTED_REASON = Symbol('rejected_reason'), | ||
RESOLVED_VALUE = Symbol('resolved_value'), | ||
START_EXECUTOR = Symbol('start_executor'), | ||
ON_FULFILLED = Symbol('on_fulfilled'), | ||
SUB_PLEDGES = Symbol('sub_pledges'), | ||
ON_CANCELLED = Symbol('on_cancelled'), | ||
SUB_PLEDGES = Symbol('sub_pledges'), | ||
ON_REJECTED = Symbol('on_rejected'), | ||
DO_RESOLVE = Symbol('do_resolve'), | ||
ON_FINALLY = Symbol('on_finally'), | ||
DO_FINALLY = Symbol('do_finally'), | ||
DO_REJECT = Symbol('do_reject'), | ||
EXECUTOR = Symbol('executor'), | ||
UPDATED = Symbol('updated'), | ||
|
@@ -92,6 +96,15 @@ AbstractPledge.setProperty({ | |
*/ | ||
[ON_REJECTED]: null, | ||
|
||
/** | ||
* An array of tasks to perform when this pledge is cancelled | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
[ON_CANCELLED]: null, | ||
|
||
/** | ||
* The eventual resolved value | ||
* | ||
|
@@ -132,17 +145,6 @@ AbstractPledge.setProperty({ | |
*/ | ||
_durations: null, | ||
|
||
/** | ||
* Property that could be a function to cancel the pledge | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.7.0 | ||
* @version 0.7.0 | ||
* | ||
* @type {Function} | ||
*/ | ||
cancel: null, | ||
|
||
/** | ||
* Warn when an error is not caught | ||
* | ||
|
@@ -519,6 +521,111 @@ AbstractPledge.setMethod(function reportProgressPart(parts) {}); | |
*/ | ||
AbstractPledge.setMethod(function _addProgressPledge(pledge) {}); | ||
|
||
/** | ||
* Cancel the pledge | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function cancel() { | ||
|
||
if (!this.isPending()) { | ||
return; | ||
} | ||
|
||
this[STATE] = CANCELLED; | ||
|
||
// Always do the on-cancel tasks as swiftly as possible | ||
return Swift.all(this[ON_CANCELLED]).finally(() => this[DO_FINALLY]()); | ||
}); | ||
|
||
/** | ||
* Do the given task when this pledge is cancelled | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function onCancelled(task) { | ||
|
||
if (typeof task != 'function') { | ||
return; | ||
} | ||
|
||
if (!this.isPending()) { | ||
|
||
if (this.isCancelled() && task) { | ||
task(); | ||
} | ||
|
||
return; | ||
} | ||
|
||
if (!this[ON_CANCELLED]) { | ||
this[ON_CANCELLED] = []; | ||
} | ||
|
||
this[ON_CANCELLED].push(next => Swift.done(task(), next)); | ||
}); | ||
|
||
/** | ||
* Do all the finally callbacks | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(DO_FINALLY, function doFinally() { | ||
while (this[ON_FINALLY]?.length) { | ||
this[ON_FINALLY].shift()(); | ||
} | ||
}); | ||
|
||
/** | ||
* Has this pledge been resolved? | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function isResolved() { | ||
return this[STATE] === RESOLVED; | ||
}); | ||
|
||
/** | ||
* Has this pledge been rejected? | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function isRejected() { | ||
return this[STATE] === REJECTED; | ||
}); | ||
|
||
/** | ||
* Has this pledge been cancelled? | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function isCancelled() { | ||
return this[STATE] === CANCELLED; | ||
}); | ||
|
||
/** | ||
* Is this pledge still pending? | ||
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.9.1 | ||
* @version 0.9.1 | ||
*/ | ||
AbstractPledge.setMethod(function isPending() { | ||
return this[STATE] === PENDING; | ||
}); | ||
|
||
/** | ||
* The BasePledge Class | ||
* | ||
|
@@ -1075,15 +1182,28 @@ Pledge.setMethod('catch', function _catch(on_rejected) { | |
* | ||
* @author Jelle De Loecker <[email protected]> | ||
* @since 0.5.6 | ||
* @version 0.5.6 | ||
* @version 0.9.1 | ||
* | ||
* @param {Function} on_finally | ||
* | ||
* @return {Pledge} | ||
*/ | ||
Pledge.setMethod('finally', function _finally(on_finally) { | ||
|
||
var constructor = this.constructor; | ||
let constructor = this.constructor; | ||
|
||
if (this.isPending() || this.isCancelled()) { | ||
if (!this[ON_FINALLY]) { | ||
this[ON_FINALLY] = []; | ||
} | ||
|
||
// We keep this in an array in case the pledge gets cancelled | ||
this[ON_FINALLY].push(on_finally); | ||
|
||
if (this.isCancelled()) { | ||
return this[DO_FINALLY](); | ||
} | ||
} | ||
|
||
return this.then( | ||
function afterResolved(value) { | ||
|
@@ -1374,8 +1494,9 @@ Swift.setMethod(DO_RESOLVE, function _doResolve(value) { | |
|
||
this[ON_REJECTED].length = 0; | ||
} | ||
}); | ||
|
||
this[DO_FINALLY](); | ||
}); | ||
|
||
/** | ||
* Reject with the given reason | ||
|
@@ -1393,6 +1514,7 @@ Swift.setMethod(function reject(reason) { | |
} | ||
|
||
this[DO_REJECT](reason); | ||
this[DO_FINALLY](); | ||
}); | ||
|
||
/** | ||
|
Oops, something went wrong.