Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add abort request polyfill and update types #148

Merged
merged 2 commits into from
May 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,34 @@ clientB.interceptors.request.use(

## Cancel request

### Use AbortController

Base on [AbortController](https://developer.mozilla.org/en-US/docs/Web/API/AbortController) that allows you to abort one or more Web requests as and when desired.

```javascript
import Request, { AbortController } from 'umi-request';

const controller = new AbortController(); // create a controller
const { signal } = controller; // grab a reference to its associated AbortSignal object using the AbortController.signal property

signal.addEventListener('abort', () => {
console.log('aborted!');
});

Request('/api/response_after_1_sec', {
signal, // pass in the AbortSignal as an option inside the request's options object (see {signal}, below). This associates the signal and controller with the fetch request and allows us to abort it by calling AbortController.abort(),
});

// 取消请求
setTimeout(() => {
controller.abort(); // Aborts a DOM request before it has completed. This is able to abort fetch requests, consumption of any response Body, and streams.
}, 100);
```

### Use Cancel Token

> Cancel Token still work, but we don’t recommend using them in the new code.

1. You can cancel a request using a cancel token.

```javascript
Expand Down Expand Up @@ -770,27 +798,6 @@ Request.get('/api/cancel', {
cancel();
```

3. create AbortCOntroller cancel

```javascript
import Request, { AbortController } from 'umi-request';

const controller = new AbortController();
const { signal } = controller;

signal.addEventListener('abort', () => {
console.log('aborted!');
});

Request('http://127.0.0.1:3009/', {
signal,
});
// 取消请求
setTimeout(() => {
controller.abort();
}, 1000);
```

## Cases

### How to get Response Headers
Expand Down
53 changes: 32 additions & 21 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -715,11 +715,41 @@ clientB.interceptors.request.use(
);
```

## 取消请求
## 中止请求

### 通过 AbortController 来中止请求

基于 [AbortController](https://developer.mozilla.org/zh-CN/docs/Web/API/FetchController) 方案来中止一个或多个DOM请求

```javascript
import Request, { AbortController } from 'umi-request';

const controller = new AbortController(); // 创建一个控制器
const { signal } = controller; // 返回一个 AbortSignal 对象实例,它可以用来 with/abort 一个 DOM 请求。

signal.addEventListener('abort', () => {
console.log('aborted!');
});

Request('/api/response_after_1_sec', {
signal, // 这将信号和控制器与获取请求相关联然后允许我们通过调用 AbortController.abort() 中止请求
});

// 取消请求
setTimeout(() => {
controller.abort(); // 中止一个尚未完成的DOM请求。这能够中止 fetch 请求,任何响应Body的消费者和流。
}, 100);
```

### 使用cancel token 方案来中止请求

> Cancel Token 将逐步退出历史舞台,推荐使用 AbortController 来实现请求中止。


你可以通过 **cancel token** 来取消一个请求

> cancel token API 是基于已被撤销的 [cancelable-promises 方案](https://github.com/tc39/proposal-cancelable-promises)
> cancel token API 是基于已被撤销的 [cancelable-promises 方案](https://github.com/tc39/proposal-cancelable-promises);


1. 你可以通过 **CancelToken.source** 来创建一个 cancel token,如下所示:

Expand Down Expand Up @@ -770,26 +800,7 @@ Request.get('/api/cancel', {
cancel();
```

3. 通过 AbortCOntroller 取消

```javascript
import Request, { AbortController } from 'umi-request';

const controller = new AbortController();
const { signal } = controller;

signal.addEventListener('abort', () => {
console.log('aborted!');
});

Request('http://127.0.0.1:3009/', {
signal,
});
// 取消请求
setTimeout(() => {
controller.abort();
}, 1000);
```

## 案例

Expand Down
21 changes: 20 additions & 1 deletion src/cancel/abortControllerCancel.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
import AbortController from 'abort-controller';
import { AbortController as AcAbortController, AbortSignal as AcAbortSignal } from 'abort-controller';

let AbortController = undefined;
let AbortSignal = undefined;

const g =
typeof self !== 'undefined'
? self
: typeof window !== 'undefined'
? window
: typeof global !== 'undefined'
? global
: /* otherwise */ undefined;

if (g) {
AbortController = typeof g.AbortController !== 'undefined' ? g.AbortController : AcAbortController;
AbortSignal = typeof g.AbortSignal !== 'undefined' ? g.AbortSignal : AcAbortSignal;
}

export default AbortController;

export { AbortController, AbortSignal };
5 changes: 3 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import request, { extend, fetch } from './request';
import Onion from './onion';
import { RequestError, ResponseError } from './utils';
import AbortController from './cancel/abortControllerCancel';
import { AbortController, AbortSignal } from './cancel/abortControllerCancel';

export { extend, RequestError, ResponseError, Onion, fetch, AbortController, AbortSignal };

export { extend, RequestError, ResponseError, Onion, fetch, AbortController };
export default request;
41 changes: 41 additions & 0 deletions test/cancel/abortControllerCancel.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import createTestServer from 'create-test-server';
import request, { AbortController } from '../../src/index';

const writeData = (data, res) => {
res.setHeader('access-control-allow-origin', '*');
res.send(data);
};

describe('test abortController', () => {
let server;

beforeAll(async () => {
server = await createTestServer();
});

afterAll(() => {
server.close();
});

const prefix = api => `${server.url}${api}`;

jest.useFakeTimers();

it('test request abort', () => {
expect.assertions(2);
server.get('/test/abort1', (req, res) => {
setTimeout(() => {
writeData(req.query, res);
}, 2000);
});

const controller = new AbortController();
const { signal } = controller;
setTimeout(() => {
controller.abort();
}, 500);
expect(signal.aborted).toBe(false);
jest.runAllTimers();
expect(signal.aborted).toBe(true);
});
});
4 changes: 4 additions & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export interface RequestOptionsInit extends RequestInit {
getResponse?: boolean;
validateCache?: (url: string, options: RequestOptionsInit) => boolean;
__umiRequestCoreType__?: string;
[key: string]: any;
}

export interface RequestOptionsWithoutResponse extends RequestOptionsInit {
Expand Down Expand Up @@ -163,4 +164,7 @@ declare var request: RequestMethod;

export declare var fetch: RequestMethod;

export declare var AbortController: { prototype: AbortController; new (): AbortController };
export declare var AbortSignal: { prototype: AbortSignal; new (): AbortSignal };

export default request;