docs: 介绍中间件

pull/49/head
zjx0905 2023-04-26 22:57:18 +08:00
parent 3931f230de
commit 63f424133e
7 changed files with 121 additions and 22 deletions

View File

@ -27,7 +27,6 @@ axios-miniprogram 是一款为小程序平台量身定制的轻量级请求库
## 特性 ## 特性
- 支持 `Typescript`,健全的类型系统,智能的 `IDE` 提示。 - 支持 `Typescript`,健全的类型系统,智能的 `IDE` 提示。
- 支持 `Promise`
- 支持 动态地址。 - 支持 动态地址。
- 支持 校验状态码。 - 支持 校验状态码。
- 支持 参数序列化。 - 支持 参数序列化。
@ -35,9 +34,10 @@ axios-miniprogram 是一款为小程序平台量身定制的轻量级请求库
- 支持 错误处理。 - 支持 错误处理。
- 支持 转换数据。 - 支持 转换数据。
- 支持 取消请求。 - 支持 取消请求。
- 支持 扩展实例。
- 支持 中间件。
- 支持 拦截器。 - 支持 拦截器。
- 支持 派生领域。 - 支持 平台适配器。
- 支持 适配器。
## 目前内部支持的平台 ## 目前内部支持的平台

View File

@ -5,26 +5,120 @@ title: 中间件
# {{ $frontmatter.title }} # {{ $frontmatter.title }}
::: tip {{ $frontmatter.title }} ::: tip {{ $frontmatter.title }}
洋葱模型中间件。 基于洋葱模型中间件。
::: :::
## 前言
如果您了解或者使用过[koa](https://github.com/koajs/koa),相信您一定十分了解什么是洋葱模型,中间件该怎么写。
中间件是一个异步函数,接收 `context``next` 两个参数。
`context` 是一个对象,提供了 `req` 对象和 `res` 对象作为其做成部分。
- `context.req`:请求配置。
- `context.res`:请求完成后服务端返回的响应体,它的初始值是 `null`,请求完成之后才能对其进行操作。
`next` 是一个异步函数,如果希望程序继续执行后续逻辑,请手动调用它。
```ts
async (ctx, next) => {
// 请求发送前
const {
// 请求配置
req,
// 此时为 null
res,
} = ctx;
// 调用 next 继续执行后续逻辑,最终发送请求
await next();
// 请求完成后
const {
// 请求配置
req,
// 服务端返回的响应体
res,
} = ctx;
};
```
## 全局中间件
可以添加全局中间件,对发送的每个请求生效。
```ts ```ts
import axios from 'axios-miniprogram'; import axios from 'axios-miniprogram';
axios.use(async (ctx, next) => { // use 会返回 this可以链式添加多个
console.log('start1'); axios
await next(); .use(async (ctx, next) => {
console.log('end1'); console.log('1');
}); await next();
console.log('4');
})
.use(async (ctx, next) => {
console.log('2');
await next();
console.log('3');
});
axios.use(async (ctx, next) => { // 洋葱模型执行顺序
console.log('start2'); // 1 -> 2 -> /test -> 3 -> 4
await next();
console.log('end2');
});
// start1 -> start2 -> /test -> end2 -> end1
axios('/test'); axios('/test');
``` ```
未完待续。。。 ## 实例中间件
可以为实例添加中间件,对实例发送的每个请求生效。
```ts
import axios from 'axios-miniprogram';
const instance = axios.create({
baseURL: 'https://api.com',
});
instance.use(async (ctx, next) => {
console.log('instance request');
await next();
console.log('instance response');
});
// instance request -> 'https://api.com/test -> instance response
instance('https://api.com/test');
```
## 扩展实例中间件
可以为扩展实例添加中间件,扩展实例同时也可以复用父级中间件。
```ts
import axios from 'axios-miniprogram';
axios.defaults.baseURL = 'https://api.com';
axios.use(async (ctx, next) => {
console.log('axios request');
await next();
console.log('axios response');
});
const instance = axios.extend({
baseURL: '/test',
});
instance.use(async (ctx, next) => {
console.log('instance request');
await next();
console.log('instance response');
});
// 复用父级中间件
// axios request -> instance request -> https://api.com/test/uesr -> instance response -> axios response
instance('/user');
```

View File

@ -5,7 +5,7 @@ title: 请求拦截器
# {{ $frontmatter.title }} # {{ $frontmatter.title }}
::: tip {{ $frontmatter.title }} ::: tip {{ $frontmatter.title }}
用于请求发前拦截请求。 用于请求发前拦截请求。
通常会用于转换请求配置,或实现一些自定义功能。 通常会用于转换请求配置,或实现一些自定义功能。
::: :::

View File

@ -5,7 +5,7 @@ title: 转换数据
# {{ $frontmatter.title }} # {{ $frontmatter.title }}
::: tip {{ $frontmatter.title }} ::: tip {{ $frontmatter.title }}
请求发前转换请求数据,响应到达 `then` 之前转换响应数据。 请求发前转换请求数据,响应到达 `then` 之前转换响应数据。
::: :::
## 转换请求数据 ## 转换请求数据

View File

@ -25,6 +25,10 @@
"homepage": "https://axios-miniprogram.com", "homepage": "https://axios-miniprogram.com",
"license": "MIT", "license": "MIT",
"type": "module", "type": "module",
"engines": {
"node": ">=16",
"pnpm": ">=7"
},
"scripts": { "scripts": {
"cz": "simple-git-hooks && czg", "cz": "simple-git-hooks && czg",
"build": "esno scripts/build.ts", "build": "esno scripts/build.ts",

View File

@ -470,6 +470,7 @@ export default class Axios {
}); });
chain.push(errorHandler); chain.push(errorHandler);
const source = Promise.resolve(mergeConfig(this.defaults, config));
return chain.reduce( return chain.reduce(
(next, { resolved, rejected }) => (next, { resolved, rejected }) =>
next.then( next.then(
@ -477,7 +478,7 @@ export default class Axios {
resolved, resolved,
rejected, rejected,
), ),
Promise.resolve(mergeConfig(this.defaults, config)), source,
) as Promise<AxiosResponse>; ) as Promise<AxiosResponse>;
}; };

View File

@ -115,7 +115,7 @@ describe('src/request/cancel.ts', () => {
expect(() => s.token.throwIfRequested()).toThrowError('1'); expect(() => s.token.throwIfRequested()).toThrowError('1');
}); });
test('应该可以在请求发之前取消', async () => { test('应该可以在请求发之前取消', async () => {
const cb = vi.fn(); const cb = vi.fn();
const s = CancelToken.source(); const s = CancelToken.source();
@ -131,7 +131,7 @@ describe('src/request/cancel.ts', () => {
expect(isCancel(cb.mock.calls[0][0])).toBeTruthy(); expect(isCancel(cb.mock.calls[0][0])).toBeTruthy();
}); });
test('应该可以在请求发之后取消', async () => { test('应该可以在请求发之后取消', async () => {
const cb = vi.fn(); const cb = vi.fn();
const s = CancelToken.source(); const s = CancelToken.source();