最近用 @kmi 框架的时候,注意到其封装的 request
函数有如下代码:
1const request: IRequest = (url: string, opts: any = { method: "GET" }) => {
2 return new Promise((resolve, reject) => {
3 querySomething()
4 handleResponse(res);
5 })
6 .catch((error) => {
7 try {
8 handler(error, opts, config);
9 } catch (e) {
10 reject(e);
11 }
12 });
13 });
14};
代码大意为:
- 执行某个封装好的异步请求
querySomething
- 捕获异常
- 将异常扔给
handler
处理
此处省略了正确执行的时候进行 resolve
操作,只保留了 reject
的逻辑。
问题在于:假设 handler
函数成功运行,那么当前的 Promise
对象状态就不会被更新,保持 pending
状态不变。
假设某个组件调用了 request
方法,运行时报错了,由于 Promise
对象状态一直保留在 Pending
,后续代码永远不会被执行。
思考 Link to heading
改变 Promise 通常的使用方式,在此处似乎是有道理的:保证请求被统一的处理函数接管,除非处理函数本身出错,否则不报错。
但是如果不了解这一特性的开发者使用 request
函数后,可能会对自己代码逻辑不运行产生疑惑;另一方面,需要开发者在使用 request
请求时,即使 request
之后的代码不运行也不影响正常的代码逻辑。