|
'use strict'; |
|
|
|
import CanceledError from './CanceledError.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CancelToken { |
|
constructor(executor) { |
|
if (typeof executor !== 'function') { |
|
throw new TypeError('executor must be a function.'); |
|
} |
|
|
|
let resolvePromise; |
|
|
|
this.promise = new Promise(function promiseExecutor(resolve) { |
|
resolvePromise = resolve; |
|
}); |
|
|
|
const token = this; |
|
|
|
|
|
this.promise.then(cancel => { |
|
if (!token._listeners) return; |
|
|
|
let i = token._listeners.length; |
|
|
|
while (i-- > 0) { |
|
token._listeners[i](cancel); |
|
} |
|
token._listeners = null; |
|
}); |
|
|
|
|
|
this.promise.then = onfulfilled => { |
|
let _resolve; |
|
|
|
const promise = new Promise(resolve => { |
|
token.subscribe(resolve); |
|
_resolve = resolve; |
|
}).then(onfulfilled); |
|
|
|
promise.cancel = function reject() { |
|
token.unsubscribe(_resolve); |
|
}; |
|
|
|
return promise; |
|
}; |
|
|
|
executor(function cancel(message, config, request) { |
|
if (token.reason) { |
|
|
|
return; |
|
} |
|
|
|
token.reason = new CanceledError(message, config, request); |
|
resolvePromise(token.reason); |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
throwIfRequested() { |
|
if (this.reason) { |
|
throw this.reason; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
subscribe(listener) { |
|
if (this.reason) { |
|
listener(this.reason); |
|
return; |
|
} |
|
|
|
if (this._listeners) { |
|
this._listeners.push(listener); |
|
} else { |
|
this._listeners = [listener]; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsubscribe(listener) { |
|
if (!this._listeners) { |
|
return; |
|
} |
|
const index = this._listeners.indexOf(listener); |
|
if (index !== -1) { |
|
this._listeners.splice(index, 1); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
static source() { |
|
let cancel; |
|
const token = new CancelToken(function executor(c) { |
|
cancel = c; |
|
}); |
|
return { |
|
token, |
|
cancel |
|
}; |
|
} |
|
} |
|
|
|
export default CancelToken; |
|
|