mirror of
https://github.com/tenrok/axios.git
synced 2026-06-20 20:00:40 +03:00
Merge pull request #452 from nickuraltsev/cancel
Adding support for request cancellation
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- node
|
||||||
email:
|
email:
|
||||||
on_failure: change
|
on_failure: change
|
||||||
on_success: never
|
on_success: never
|
||||||
|
|||||||
@@ -305,7 +305,12 @@ These are the available config options for making requests. Only the `url` is re
|
|||||||
proxy: {
|
proxy: {
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 9000
|
port: 9000
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// `cancelToken` specifies a cancel token that can be used to cancel the request
|
||||||
|
// (see Cancellation section below for details)
|
||||||
|
cancelToken: new CancelToken(function (cancel) {
|
||||||
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -457,6 +462,49 @@ axios.get('/user/12345', {
|
|||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Cancellation
|
||||||
|
|
||||||
|
You can cancel a request using a *cancel token*.
|
||||||
|
|
||||||
|
> The axios cancel token API is based on the [cancelable promises proposal](https://github.com/tc39/proposal-cancelable-promises), which is currently at Stage 1.
|
||||||
|
|
||||||
|
You can create a cancel token using the `CancelToken.source` factory as shown below:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var CancelToken = axios.CancelToken;
|
||||||
|
var source = CancelToken.source();
|
||||||
|
|
||||||
|
axios.get('/user/12345', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch(function(thrown) {
|
||||||
|
if (axios.isCancel(thrown)) {
|
||||||
|
console.log('Request canceled', thrown.message);
|
||||||
|
} else {
|
||||||
|
// handle error
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// cancel the request (the message parameter is optional)
|
||||||
|
source.cancel('Operation canceled by the user.');
|
||||||
|
```
|
||||||
|
|
||||||
|
You can also create a cancel token by passing an executor function to the `CancelToken` constructor:
|
||||||
|
|
||||||
|
```js
|
||||||
|
var CancelToken = axios.CancelToken;
|
||||||
|
var cancel;
|
||||||
|
|
||||||
|
axios.get('/user/12345', {
|
||||||
|
cancelToken: new CancelToken(function executor(c) {
|
||||||
|
// An executor function receives a cancel function as a parameter
|
||||||
|
cancel = c;
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// cancel the request
|
||||||
|
cancel();
|
||||||
|
```
|
||||||
|
|
||||||
## Semver
|
## Semver
|
||||||
|
|
||||||
Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes.
|
Until axios reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.5.1`, and `0.5.4` will have the same API, but `0.6.0` will have breaking changes.
|
||||||
|
|||||||
Vendored
+32
@@ -41,6 +41,7 @@ export interface AxiosRequestConfig {
|
|||||||
httpAgent?: any;
|
httpAgent?: any;
|
||||||
httpsAgent?: any;
|
httpsAgent?: any;
|
||||||
proxy?: AxiosProxyConfig;
|
proxy?: AxiosProxyConfig;
|
||||||
|
cancelToken?: CancelToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AxiosResponse {
|
export interface AxiosResponse {
|
||||||
@@ -66,6 +67,34 @@ export interface Promise<V> {
|
|||||||
export interface AxiosPromise extends Promise<AxiosResponse> {
|
export interface AxiosPromise extends Promise<AxiosResponse> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CancelStatic {
|
||||||
|
new (message?: string): Cancel;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Cancel {
|
||||||
|
message: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Canceler {
|
||||||
|
(message?: string): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CancelTokenStatic {
|
||||||
|
new (executor: (cancel: Canceler) => void): CancelToken;
|
||||||
|
source(): CancelTokenSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CancelToken {
|
||||||
|
promise: Promise<Cancel>;
|
||||||
|
reason?: Cancel;
|
||||||
|
throwIfRequested(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CancelTokenSource {
|
||||||
|
token: CancelToken;
|
||||||
|
cancel: Canceler;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AxiosInterceptorManager<V> {
|
export interface AxiosInterceptorManager<V> {
|
||||||
use(onFulfilled: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;
|
use(onFulfilled: (value: V) => V | Promise<V>, onRejected?: (error: any) => any): number;
|
||||||
eject(id: number): void;
|
eject(id: number): void;
|
||||||
@@ -90,6 +119,9 @@ export interface AxiosStatic extends AxiosInstance {
|
|||||||
(config: AxiosRequestConfig): AxiosPromise;
|
(config: AxiosRequestConfig): AxiosPromise;
|
||||||
(url: string, config?: AxiosRequestConfig): AxiosPromise;
|
(url: string, config?: AxiosRequestConfig): AxiosPromise;
|
||||||
create(config?: AxiosRequestConfig): AxiosInstance;
|
create(config?: AxiosRequestConfig): AxiosInstance;
|
||||||
|
Cancel: CancelStatic;
|
||||||
|
CancelToken: CancelTokenStatic;
|
||||||
|
isCancel(value: any): boolean;
|
||||||
all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
|
all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
|
||||||
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,6 +185,15 @@ module.exports = function httpAdapter(config) {
|
|||||||
}, config.timeout);
|
}, config.timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.cancelToken) {
|
||||||
|
// Handle cancellation
|
||||||
|
config.cancelToken.promise.then(function onCanceled(cancel) {
|
||||||
|
req.abort();
|
||||||
|
reject(cancel);
|
||||||
|
aborted = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Send the request
|
// Send the request
|
||||||
if (utils.isStream(data)) {
|
if (utils.isStream(data)) {
|
||||||
data.pipe(req);
|
data.pipe(req);
|
||||||
|
|||||||
@@ -153,6 +153,15 @@ module.exports = function xhrAdapter(config) {
|
|||||||
request.upload.addEventListener('progress', config.onUploadProgress);
|
request.upload.addEventListener('progress', config.onUploadProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.cancelToken) {
|
||||||
|
// Handle cancellation
|
||||||
|
config.cancelToken.promise.then(function onCanceled(cancel) {
|
||||||
|
request.abort();
|
||||||
|
reject(cancel);
|
||||||
|
// Clean up request
|
||||||
|
request = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (requestData === undefined) {
|
if (requestData === undefined) {
|
||||||
requestData = null;
|
requestData = null;
|
||||||
|
|||||||
@@ -34,6 +34,11 @@ axios.create = function create(defaultConfig) {
|
|||||||
return createInstance(defaultConfig);
|
return createInstance(defaultConfig);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Expose Cancel & CancelToken
|
||||||
|
axios.Cancel = require('./cancel/Cancel');
|
||||||
|
axios.CancelToken = require('./cancel/CancelToken');
|
||||||
|
axios.isCancel = require('./cancel/isCancel');
|
||||||
|
|
||||||
// Expose all/spread
|
// Expose all/spread
|
||||||
axios.all = function all(promises) {
|
axios.all = function all(promises) {
|
||||||
return Promise.all(promises);
|
return Promise.all(promises);
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A `Cancel` is an object that is thrown when an operation is canceled.
|
||||||
|
*
|
||||||
|
* @class
|
||||||
|
* @param {string=} message The message.
|
||||||
|
*/
|
||||||
|
function Cancel(message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cancel.prototype.toString = function toString() {
|
||||||
|
return 'Cancel' + (this.message ? ': ' + this.message : '');
|
||||||
|
};
|
||||||
|
|
||||||
|
Cancel.prototype.__CANCEL__ = true;
|
||||||
|
|
||||||
|
module.exports = Cancel;
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
'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;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = function isCancel(value) {
|
||||||
|
return !!(value && value.__CANCEL__);
|
||||||
|
};
|
||||||
@@ -2,8 +2,18 @@
|
|||||||
|
|
||||||
var utils = require('./../utils');
|
var utils = require('./../utils');
|
||||||
var transformData = require('./transformData');
|
var transformData = require('./transformData');
|
||||||
|
var isCancel = require('../cancel/isCancel');
|
||||||
var defaults = require('../defaults');
|
var defaults = require('../defaults');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws a `Cancel` if cancellation has been requested.
|
||||||
|
*/
|
||||||
|
function throwIfCancellationRequested(config) {
|
||||||
|
if (config.cancelToken) {
|
||||||
|
config.cancelToken.throwIfRequested();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch a request to the server using the configured adapter.
|
* Dispatch a request to the server using the configured adapter.
|
||||||
*
|
*
|
||||||
@@ -11,6 +21,8 @@ var defaults = require('../defaults');
|
|||||||
* @returns {Promise} The Promise to be fulfilled
|
* @returns {Promise} The Promise to be fulfilled
|
||||||
*/
|
*/
|
||||||
module.exports = function dispatchRequest(config) {
|
module.exports = function dispatchRequest(config) {
|
||||||
|
throwIfCancellationRequested(config);
|
||||||
|
|
||||||
// Ensure headers exist
|
// Ensure headers exist
|
||||||
config.headers = config.headers || {};
|
config.headers = config.headers || {};
|
||||||
|
|
||||||
@@ -38,6 +50,8 @@ module.exports = function dispatchRequest(config) {
|
|||||||
var adapter = config.adapter || defaults.adapter;
|
var adapter = config.adapter || defaults.adapter;
|
||||||
|
|
||||||
return adapter(config).then(function onAdapterResolution(response) {
|
return adapter(config).then(function onAdapterResolution(response) {
|
||||||
|
throwIfCancellationRequested(config);
|
||||||
|
|
||||||
// Transform response data
|
// Transform response data
|
||||||
response.data = transformData(
|
response.data = transformData(
|
||||||
response.data,
|
response.data,
|
||||||
@@ -46,16 +60,20 @@ module.exports = function dispatchRequest(config) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}, function onAdapterRejection(error) {
|
}, function onAdapterRejection(reason) {
|
||||||
// Transform response data
|
if (!isCancel(reason)) {
|
||||||
if (error && error.response) {
|
throwIfCancellationRequested(config);
|
||||||
error.response.data = transformData(
|
|
||||||
error.response.data,
|
// Transform response data
|
||||||
error.response.headers,
|
if (reason && reason.response) {
|
||||||
config.transformResponse
|
reason.response.data = transformData(
|
||||||
);
|
reason.response.data,
|
||||||
|
reason.response.headers,
|
||||||
|
config.transformResponse
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.reject(error);
|
return Promise.reject(reason);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ describe('static api', function () {
|
|||||||
it('should have factory method', function () {
|
it('should have factory method', function () {
|
||||||
expect(typeof axios.create).toEqual('function');
|
expect(typeof axios.create).toEqual('function');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should have Cancel, CancelToken, and isCancel properties', function () {
|
||||||
|
expect(typeof axios.Cancel).toEqual('function');
|
||||||
|
expect(typeof axios.CancelToken).toEqual('function');
|
||||||
|
expect(typeof axios.isCancel).toEqual('function');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('instance api', function () {
|
describe('instance api', function () {
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
var Cancel = axios.Cancel;
|
||||||
|
var CancelToken = axios.CancelToken;
|
||||||
|
|
||||||
|
describe('cancel', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
jasmine.Ajax.install();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
jasmine.Ajax.uninstall();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when called before sending request', function() {
|
||||||
|
it('rejects Promise with a Cancel object', function (done) {
|
||||||
|
var source = CancelToken.source();
|
||||||
|
source.cancel('Operation has been canceled.');
|
||||||
|
axios.get('/foo', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch(function (thrown) {
|
||||||
|
expect(thrown).toEqual(jasmine.any(Cancel));
|
||||||
|
expect(thrown.message).toBe('Operation has been canceled.');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when called after request has been sent', function() {
|
||||||
|
it('rejects Promise with a Cancel object', function (done) {
|
||||||
|
var source = CancelToken.source();
|
||||||
|
axios.get('/foo/bar', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch(function (thrown) {
|
||||||
|
expect(thrown).toEqual(jasmine.any(Cancel));
|
||||||
|
expect(thrown.message).toBe('Operation has been canceled.');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
getAjaxRequest().then(function (request) {
|
||||||
|
// call cancel() when the request has been sent, but a response has not been received
|
||||||
|
source.cancel('Operation has been canceled.');
|
||||||
|
request.respondWith({
|
||||||
|
status: 200,
|
||||||
|
responseText: 'OK'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('calls abort on request object', function (done) {
|
||||||
|
var source = CancelToken.source();
|
||||||
|
var request;
|
||||||
|
axios.get('/foo/bar', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch(function() {
|
||||||
|
// jasmine-ajax sets statusText to 'abort' when request.abort() is called
|
||||||
|
expect(request.statusText).toBe('abort');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
getAjaxRequest().then(function (req) {
|
||||||
|
// call cancel() when the request has been sent, but a response has not been received
|
||||||
|
source.cancel();
|
||||||
|
request = req;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
var Cancel = require('../../../lib/cancel/Cancel');
|
||||||
|
|
||||||
|
describe('Cancel', function() {
|
||||||
|
describe('toString', function() {
|
||||||
|
it('returns correct result when message is not specified', function() {
|
||||||
|
var cancel = new Cancel();
|
||||||
|
expect(cancel.toString()).toBe('Cancel');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns correct result when message is specified', function() {
|
||||||
|
var cancel = new Cancel('Operation has been canceled.');
|
||||||
|
expect(cancel.toString()).toBe('Cancel: Operation has been canceled.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
var CancelToken = require('../../../lib/cancel/CancelToken');
|
||||||
|
var Cancel = require('../../../lib/cancel/Cancel');
|
||||||
|
|
||||||
|
describe('CancelToken', function() {
|
||||||
|
describe('constructor', function() {
|
||||||
|
it('throws when executor is not specified', function() {
|
||||||
|
expect(function() {
|
||||||
|
new CancelToken();
|
||||||
|
}).toThrowError(TypeError, 'executor must be a function.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws when executor is not a function', function() {
|
||||||
|
expect(function() {
|
||||||
|
new CancelToken(123);
|
||||||
|
}).toThrowError(TypeError, 'executor must be a function.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('reason', function() {
|
||||||
|
it('returns a Cancel if cancellation has been requested', function() {
|
||||||
|
var cancel;
|
||||||
|
var token = new CancelToken(function(c) {
|
||||||
|
cancel = c;
|
||||||
|
});
|
||||||
|
cancel('Operation has been canceled.');
|
||||||
|
expect(token.reason).toEqual(jasmine.any(Cancel));
|
||||||
|
expect(token.reason.message).toBe('Operation has been canceled.');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns undefined if cancellation has not been requested', function() {
|
||||||
|
var token = new CancelToken(function() {});
|
||||||
|
expect(token.reason).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('promise', function() {
|
||||||
|
it('returns a Promise that resolves when cancellation is requested', function(done) {
|
||||||
|
var cancel;
|
||||||
|
var token = new CancelToken(function(c) {
|
||||||
|
cancel = c;
|
||||||
|
});
|
||||||
|
token.promise.then(function onFulfilled(value) {
|
||||||
|
expect(value).toEqual(jasmine.any(Cancel));
|
||||||
|
expect(value.message).toBe('Operation has been canceled.');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
cancel('Operation has been canceled.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('throwIfRequested', function() {
|
||||||
|
it('throws if cancellation has been requested', function() {
|
||||||
|
// Note: we cannot use expect.toThrowError here as Cancel does not inherit from Error
|
||||||
|
var cancel;
|
||||||
|
var token = new CancelToken(function(c) {
|
||||||
|
cancel = c;
|
||||||
|
});
|
||||||
|
cancel('Operation has been canceled.');
|
||||||
|
try {
|
||||||
|
token.throwIfRequested();
|
||||||
|
fail('Expected throwIfRequested to throw.');
|
||||||
|
} catch (thrown) {
|
||||||
|
if (!(thrown instanceof Cancel)) {
|
||||||
|
fail('Expected throwIfRequested to throw a Cancel, but it threw ' + thrown + '.');
|
||||||
|
}
|
||||||
|
expect(thrown.message).toBe('Operation has been canceled.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not throw if cancellation has not been requested', function() {
|
||||||
|
var token = new CancelToken(function() {});
|
||||||
|
token.throwIfRequested();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('source', function() {
|
||||||
|
it('returns an object containing token and cancel function', function() {
|
||||||
|
var source = CancelToken.source();
|
||||||
|
expect(source.token).toEqual(jasmine.any(CancelToken));
|
||||||
|
expect(source.cancel).toEqual(jasmine.any(Function));
|
||||||
|
expect(source.token.reason).toBeUndefined();
|
||||||
|
source.cancel('Operation has been canceled.');
|
||||||
|
expect(source.token.reason).toEqual(jasmine.any(Cancel));
|
||||||
|
expect(source.token.reason.message).toBe('Operation has been canceled.');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
var isCancel = require('../../../lib/cancel/isCancel');
|
||||||
|
var Cancel = require('../../../lib/cancel/Cancel');
|
||||||
|
|
||||||
|
describe('isCancel', function() {
|
||||||
|
it('returns true if value is a Cancel', function() {
|
||||||
|
expect(isCancel(new Cancel())).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns false if value is not a Cancel', function() {
|
||||||
|
expect(isCancel({ foo: 'bar' })).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -11,7 +11,15 @@ describe('instance', function () {
|
|||||||
var instance = axios.create();
|
var instance = axios.create();
|
||||||
|
|
||||||
for (var prop in axios) {
|
for (var prop in axios) {
|
||||||
if (['Axios', 'create', 'all', 'spread', 'default'].indexOf(prop) > -1) {
|
if ([
|
||||||
|
'Axios',
|
||||||
|
'create',
|
||||||
|
'Cancel',
|
||||||
|
'CancelToken',
|
||||||
|
'isCancel',
|
||||||
|
'all',
|
||||||
|
'spread',
|
||||||
|
'default'].indexOf(prop) > -1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
expect(typeof instance[prop]).toBe(typeof axios[prop]);
|
expect(typeof instance[prop]).toBe(typeof axios[prop]);
|
||||||
|
|||||||
@@ -1,4 +1,15 @@
|
|||||||
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError, AxiosInstance, AxiosAdapter } from '../../';
|
import axios, {
|
||||||
|
AxiosRequestConfig,
|
||||||
|
AxiosResponse,
|
||||||
|
AxiosError,
|
||||||
|
AxiosInstance,
|
||||||
|
AxiosAdapter,
|
||||||
|
Cancel,
|
||||||
|
CancelToken,
|
||||||
|
CancelTokenSource,
|
||||||
|
Canceler
|
||||||
|
} from '../../';
|
||||||
|
|
||||||
import { Promise } from 'es6-promise';
|
import { Promise } from 'es6-promise';
|
||||||
|
|
||||||
const config: AxiosRequestConfig = {
|
const config: AxiosRequestConfig = {
|
||||||
@@ -30,7 +41,8 @@ const config: AxiosRequestConfig = {
|
|||||||
proxy: {
|
proxy: {
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 9000
|
port: 9000
|
||||||
}
|
},
|
||||||
|
cancelToken: new axios.CancelToken((cancel: Canceler) => {})
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleResponse = (response: AxiosResponse) => {
|
const handleResponse = (response: AxiosResponse) => {
|
||||||
@@ -210,3 +222,18 @@ axios.get('/user')
|
|||||||
axios.get('/user')
|
axios.get('/user')
|
||||||
.catch((error: any) => Promise.resolve('foo'))
|
.catch((error: any) => Promise.resolve('foo'))
|
||||||
.then((value: string) => {});
|
.then((value: string) => {});
|
||||||
|
|
||||||
|
// Cancellation
|
||||||
|
|
||||||
|
const source: CancelTokenSource = axios.CancelToken.source();
|
||||||
|
|
||||||
|
axios.get('/user', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch((thrown: AxiosError | Cancel) => {
|
||||||
|
if (axios.isCancel(thrown)) {
|
||||||
|
const cancel: Cancel = thrown;
|
||||||
|
console.log(cancel.message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
source.cancel('Operation has been canceled.');
|
||||||
|
|||||||
@@ -320,5 +320,21 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
testCancel: function(test) {
|
||||||
|
var source = axios.CancelToken.source();
|
||||||
|
server = http.createServer(function (req, res) {
|
||||||
|
// call cancel() when the request has been sent, but a response has not been received
|
||||||
|
source.cancel('Operation has been canceled.');
|
||||||
|
}).listen(4444, function() {
|
||||||
|
axios.get('http://localhost:4444/', {
|
||||||
|
cancelToken: source.token
|
||||||
|
}).catch(function (thrown) {
|
||||||
|
test.ok(thrown instanceof axios.Cancel, 'Promise must be rejected with a Cancel obejct');
|
||||||
|
test.equal(thrown.message, 'Operation has been canceled.');
|
||||||
|
test.done();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user