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.
119 lines
2.4 KiB
119 lines
2.4 KiB
'use strict'; |
|
|
|
var Cancel = require('./Cancel'); |
|
|
|
/** |
|
* A `CancelToken` is an object that can be used to request cancellation of an operation. |
|
* |
|
* @class |
|
* @param {Function} executor The executor function. |
|
*/ |
|
function CancelToken(executor) { |
|
if (typeof executor !== 'function') { |
|
throw new TypeError('executor must be a function.'); |
|
} |
|
|
|
var resolvePromise; |
|
|
|
this.promise = new Promise(function promiseExecutor(resolve) { |
|
resolvePromise = resolve; |
|
}); |
|
|
|
var token = this; |
|
|
|
// eslint-disable-next-line func-names |
|
this.promise.then(function(cancel) { |
|
if (!token._listeners) return; |
|
|
|
var i; |
|
var l = token._listeners.length; |
|
|
|
for (i = 0; i < l; i++) { |
|
token._listeners[i](cancel); |
|
} |
|
token._listeners = null; |
|
}); |
|
|
|
// eslint-disable-next-line func-names |
|
this.promise.then = function(onfulfilled) { |
|
var _resolve; |
|
// eslint-disable-next-line func-names |
|
var promise = new Promise(function(resolve) { |
|
token.subscribe(resolve); |
|
_resolve = resolve; |
|
}).then(onfulfilled); |
|
|
|
promise.cancel = function reject() { |
|
token.unsubscribe(_resolve); |
|
}; |
|
|
|
return promise; |
|
}; |
|
|
|
executor(function cancel(message) { |
|
if (token.reason) { |
|
// Cancellation has already been requested |
|
return; |
|
} |
|
|
|
token.reason = new Cancel(message); |
|
resolvePromise(token.reason); |
|
}); |
|
} |
|
|
|
/** |
|
* Throws a `Cancel` if cancellation has been requested. |
|
*/ |
|
CancelToken.prototype.throwIfRequested = function throwIfRequested() { |
|
if (this.reason) { |
|
throw this.reason; |
|
} |
|
}; |
|
|
|
/** |
|
* Subscribe to the cancel signal |
|
*/ |
|
|
|
CancelToken.prototype.subscribe = function subscribe(listener) { |
|
if (this.reason) { |
|
listener(this.reason); |
|
return; |
|
} |
|
|
|
if (this._listeners) { |
|
this._listeners.push(listener); |
|
} else { |
|
this._listeners = [listener]; |
|
} |
|
}; |
|
|
|
/** |
|
* Unsubscribe from the cancel signal |
|
*/ |
|
|
|
CancelToken.prototype.unsubscribe = function unsubscribe(listener) { |
|
if (!this._listeners) { |
|
return; |
|
} |
|
var index = this._listeners.indexOf(listener); |
|
if (index !== -1) { |
|
this._listeners.splice(index, 1); |
|
} |
|
}; |
|
|
|
/** |
|
* Returns an object that contains a new `CancelToken` and a function that, when called, |
|
* cancels the `CancelToken`. |
|
*/ |
|
CancelToken.source = function source() { |
|
var cancel; |
|
var token = new CancelToken(function executor(c) { |
|
cancel = c; |
|
}); |
|
return { |
|
token: token, |
|
cancel: cancel |
|
}; |
|
}; |
|
|
|
module.exports = CancelToken;
|
|
|