|
| 1 | +# tarojs-request |
| 2 | + |
| 3 | +小程序网络请求库,基于 `Taro.request` & `koa-compose` 封装, 旨在为开发者提供一个简单易用,易扩展的 api 调用方式。 |
| 4 | + |
| 5 | +## 支持的功能 |
| 6 | + |
| 7 | +- `Typescript` 支持 |
| 8 | +- `koa` 洋葱机制的 `use` 中间件机制支持 |
| 9 | +- `timeout` 支持 |
| 10 | +- 统一的`错误处理`方式 |
| 11 | + |
| 12 | +## 安装 |
| 13 | + |
| 14 | +```bash |
| 15 | +npm install --save tarojs-request |
| 16 | +``` |
| 17 | + |
| 18 | +## 快速上手 |
| 19 | + |
| 20 | +执行`GET`请求 |
| 21 | + |
| 22 | +```ts |
| 23 | +import request from 'tarojs-request'; |
| 24 | + |
| 25 | +request('https://xxx.xxx.xxx/xxx', { xxx: 'xxx' }) |
| 26 | + .then(console.log) |
| 27 | + .catch(console.log); |
| 28 | +``` |
| 29 | + |
| 30 | +执行`POST`请求 |
| 31 | + |
| 32 | +```ts |
| 33 | +import request from 'tarojs-request'; |
| 34 | + |
| 35 | +request('https://xxx.xxx.xxx/xxx', { xxx: 'xxx' }, 'POST') |
| 36 | + .then(console.log) |
| 37 | + .catch(console.log); |
| 38 | +``` |
| 39 | + |
| 40 | +## tarojs-request API |
| 41 | + |
| 42 | +- request【请求】 |
| 43 | + |
| 44 | +```ts |
| 45 | +// 类型 |
| 46 | +function request<ResData, ReqData>( |
| 47 | + url: string, |
| 48 | + data?: ReqData, |
| 49 | + method?: string, |
| 50 | + extra?: Taro.request.Option, |
| 51 | +): Promise<Taro.request.SuccessCallbackResult<Response<ResData>>>; |
| 52 | + |
| 53 | +// 案例 |
| 54 | +import request from 'tarojs-request'; |
| 55 | + |
| 56 | +request('https://xxx.xxx.xxx/xxx', { xxx: 'xxx' }, 'POST', { |
| 57 | + header: { |
| 58 | + xx: 'xxx', |
| 59 | + }, |
| 60 | +}) |
| 61 | + .then(console.log) |
| 62 | + .catch(console.log); |
| 63 | +``` |
| 64 | + |
| 65 | +- extend【创建请求实例】 |
| 66 | + |
| 67 | +```ts |
| 68 | +// 类型 |
| 69 | +function extend<ReqData>(initOptions?: Taro.request.Option<ReqData>>): Request; |
| 70 | + |
| 71 | +// 案例 |
| 72 | +import { extend } from 'tarojs-request'; |
| 73 | + |
| 74 | +const customRequest = extend({ |
| 75 | + timeout: 5000, |
| 76 | +}); |
| 77 | + |
| 78 | +customRequest('https://xxx.xxx.xxx/xxx', { xxx: 'xxx' }, 'POST', { |
| 79 | + header: { |
| 80 | + xx: 'xxx', |
| 81 | + }, |
| 82 | +}) |
| 83 | + .then(console.log) |
| 84 | + .catch(console.log); |
| 85 | +``` |
| 86 | + |
| 87 | +## 请求配置 |
| 88 | + |
| 89 | +> 以下仅列出对比 [Taro.request](https://docs.taro.zone/docs/apis/network/request/request#option) 请求配置新增的 item |
| 90 | +
|
| 91 | +| 参数 | 类型 | 默认值 | 必填 | 说明 | |
| 92 | +| -------------- | --------------------- | ------ | ---- | -------------------------------------- | |
| 93 | +| errorHandler | (error: Error) => any | - | 否 | 错误处理 | |
| 94 | +| timeoutMessage | string | - | 否 | 超时可自定义提示文案, 需先定义 timeout | |
| 95 | +| signal | AbortSignal | - | 否 | AbortSignal 终止请求 | |
| 96 | + |
| 97 | +## 响应结构 |
| 98 | + |
| 99 | +响应结构同 [Taro.request.SuccessCallbackResult](https://docs.taro.zone/docs/apis/network/request/request#successcallbackresult) 一致。 |
| 100 | + |
| 101 | +## 错误处理 |
| 102 | + |
| 103 | +```ts |
| 104 | +import request, { extend } from 'tarojs-request'; |
| 105 | + |
| 106 | +const errorHandler = function (error) { |
| 107 | + const codeMap = { |
| 108 | + '021': '发生错误啦', |
| 109 | + '022': '发生大大大大错误啦', |
| 110 | + // .... |
| 111 | + }; |
| 112 | + if (error.response) { |
| 113 | + // 请求已发送但服务端返回状态码非 2xx 的响应 |
| 114 | + console.log(error.response.status); |
| 115 | + console.log(error.response.headers); |
| 116 | + console.log(error.data); |
| 117 | + console.log(error.request); |
| 118 | + console.log(codeMap[error.data.status]); |
| 119 | + } else { |
| 120 | + // 请求初始化时出错或者没有响应返回的异常 |
| 121 | + console.log(error.message); |
| 122 | + } |
| 123 | + |
| 124 | + throw error; // 如果throw. 错误将继续抛出. |
| 125 | + |
| 126 | + // 如果return, 则将值作为返回. 'return;' 相当于return undefined, 在处理结果时判断response是否有值即可. |
| 127 | + // return {some: 'data'}; |
| 128 | +}; |
| 129 | + |
| 130 | +// 1. 作为统一错误处理 |
| 131 | +const extendRequest = extend({ errorHandler }); |
| 132 | + |
| 133 | +// 2. 单独特殊处理, 如果配置了统一处理, 但某个api需要特殊处理. 则在请求时, 将errorHandler作为参数传入. |
| 134 | +request('/api/v1/xxx', { x: 'xxx' }, 'GET', { errorHandler }); |
| 135 | + |
| 136 | +// 3. 通过 Promise.catch 做错误处理 |
| 137 | +request('/api/v1/xxx') |
| 138 | + .then(function (response) { |
| 139 | + console.log(response); |
| 140 | + }) |
| 141 | + .catch(function (error) { |
| 142 | + return errorHandler(error); |
| 143 | + }); |
| 144 | +``` |
| 145 | + |
| 146 | +## 中间件 |
| 147 | + |
| 148 | +同 Koa 中间件创建和使用保持一致,让开发者优雅地做请求前后的增强处理。 |
| 149 | + |
| 150 | +request.use((ctx, next)) |
| 151 | + |
| 152 | +- ctx(Object):上下文对象,包括 req 和 res 对象 |
| 153 | +- next(Function):调用下一个中间件的函数 |
| 154 | + |
| 155 | +案例 |
| 156 | + |
| 157 | +```ts |
| 158 | +import Taro from '@tarojs/taro'; |
| 159 | +import request from 'tarojs-request'; |
| 160 | +import { Middleware } from 'koa-compose'; |
| 161 | +import { Context } from '../type'; |
| 162 | + |
| 163 | +/** |
| 164 | + * Check network |
| 165 | + * |
| 166 | + * @param {*} _ctx |
| 167 | + * @param {*} next |
| 168 | + * @return {*} |
| 169 | + */ |
| 170 | +const networkCheckMiddleware: Middleware<Context> = async (_ctx, next) => { |
| 171 | + // 获取网络状态 |
| 172 | + const networkState = await Taro.getNetworkType(); |
| 173 | + if (networkState.networkType === 'none') { |
| 174 | + throw new Error('当前网络不可用'); |
| 175 | + } |
| 176 | + await next(); |
| 177 | +}; |
| 178 | + |
| 179 | +request.use(networkCheckMiddleware); |
| 180 | +``` |
| 181 | + |
| 182 | +tarojs-request 提供了一个内置中间件 `networkCheckMiddleware` |
| 183 | + |
| 184 | +## 中止请求 |
| 185 | + |
| 186 | +通过 AbortController 来中止请求 |
| 187 | + |
| 188 | +```ts |
| 189 | +import request, { AbortController } from 'tarojs-request'; |
| 190 | + |
| 191 | +const controller = new AbortController(); // 创建一个控制器 |
| 192 | +const { signal } = controller; // 返回一个 AbortSignal 对象实例,它可以用来 with/abort 一个 DOM 请求。 |
| 193 | + |
| 194 | +signal.addEventListener('abort', () => { |
| 195 | + console.log('aborted!'); |
| 196 | +}); |
| 197 | + |
| 198 | +request('/api/response_after_1_sec', { |
| 199 | + signal, // 这将信号和控制器与获取请求相关联然后允许我们通过调用 AbortController.abort() 中止请求 |
| 200 | +}); |
| 201 | + |
| 202 | +// 取消请求 |
| 203 | +setTimeout(() => { |
| 204 | + controller.abort(); // 中止一个尚未完成的 DOM 请求。这能够中止 fetch 请求,任何响应 Body 的消费者和流。 |
| 205 | +}, 100); |
| 206 | +``` |
0 commit comments