欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。
关于 uni.addInterceptor('request', { success() {}, returnValue() {} }) 中 success 和 returnValue 的底层执行逻辑以及你遇到的问题,原因如下:
1. success 与 returnValue 的执行机制与关系
returnValue:在 uni.request 方法调用后触发,用于处理返回值。它接收的参数通常是 uni.request 返回的 Promise 对象(在 Vue3 项目中)或 RequestTask 对象(在某些平台或特定条件下)。它的作用是对 API 的最终返回值进行二次处理,如果你在这里返回了一个新的 Promise,外部调用者通过 .then().catch() 拿到的就是你这里返回的 Promise 结果。
success:成功回调拦截。它在底层请求成功并触发成功回调时执行。你可以在这个回调中修改响应数据,或者通过 return false 来阻止后续成功逻辑的执行。
2. 为什么在 success 里面 return Promise.reject,returnValue 里面监听不到?
success 回调的返回值并不会传递给 returnValue,也不会改变 uni.request 原始 Promise 的状态。
returnValue 接收到的 p 是 uni.request 原始的 Promise 对象,它的状态由底层网络请求的结果决定。只要网络请求成功(比如 HTTP 状态码为 200),p 的状态就是 resolved。你在 success 中 return Promise.reject 只是让 success 回调函数本身返回了一个被拒绝的 Promise,但这并不会影响已经处于 resolved 状态的原始 Promise p。因此,returnValue 里的 p.then 依然会正常进入成功回调,catch 自然也就监听不到。
3. 正确的实现方式
如果你希望在请求成功但业务状态码异常时,让外部的 catch 能够捕获到错误,应该在 returnValue 中重新包装 Promise,并在其中进行判断和主动 reject。
参考以下示例代码(适用于 Vue3 项目):
uni.addInterceptor('request', {
invoke(args) {
// 请求前拦截
},
returnValue(p) {
// p 为 uni.request 原始返回的 Promise
return new Promise((resolve, reject) => {
p.then((res) => {
// 这里的 res 包含 statusCode, data 等信息
if (res.statusCode !== 200) {
// 状态码异常,主动 reject,外部会进入 catch
reject({ status: res.statusCode, message: '请求失败' })
} else {
// 业务逻辑判断,例如后端返回的 code 不为 0
// if (res.data.code !== 0) {
// reject(res.data)
// } else {
// resolve(res.data) // 正常返回数据
// }
resolve(res.data)
}
}).catch((err) => {
// 网络请求本身的错误,直接 reject
reject(err)
})
})
},
success(args) {
// 成功回调拦截,可以修改响应数据
// args.data.code = 1
},
fail(err) {
// 失败回调拦截
}
})
本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent
4. 注意事项
- Vue2 与 Vue3 差异:Vue2 和 Vue3 项目的 API Promise 化返回格式不一致。Vue2 对部分 API 进行了 Promise 封装,返回数据的第一个参数是错误对象,第二个参数是返回数据,且内部对错误进行了拦截,使用
catch 拿不到报错信息;Vue3 则调用成功进入 then,失败进入 catch。请根据你的项目类型调整 returnValue 中的处理逻辑。
- 平台差异:在 H5 平台,
returnValue 接收到的参数可能不是 Promise,而是 XMLHttpRequest 对象,直接修改其属性可能会提示只读。如果是微信小程序,可能需要通过 args.onHeadersReceived 来获取状态码并进行分流处理。具体实现需根据目标平台进行条件编译和适配。
参考文档:
2 个回复
7***@qq.com (作者)
AI回答的并不正确,我在success中return Promise.reject, returnValue 中的 p.then.catch,代码 无论是then还是catch都不会执行,只有什么都不做,才会执行then
Ask小助手
关于
uni.addInterceptor('request', { success() {}, returnValue() {} })中success和returnValue的底层执行逻辑以及你遇到的问题,原因如下:1.
success与returnValue的执行机制与关系returnValue:在uni.request方法调用后触发,用于处理返回值。它接收的参数通常是uni.request返回的 Promise 对象(在 Vue3 项目中)或 RequestTask 对象(在某些平台或特定条件下)。它的作用是对 API 的最终返回值进行二次处理,如果你在这里返回了一个新的 Promise,外部调用者通过.then().catch()拿到的就是你这里返回的 Promise 结果。success:成功回调拦截。它在底层请求成功并触发成功回调时执行。你可以在这个回调中修改响应数据,或者通过return false来阻止后续成功逻辑的执行。2. 为什么在
success里面return Promise.reject,returnValue里面监听不到?success回调的返回值并不会传递给returnValue,也不会改变uni.request原始 Promise 的状态。returnValue接收到的p是uni.request原始的 Promise 对象,它的状态由底层网络请求的结果决定。只要网络请求成功(比如 HTTP 状态码为 200),p的状态就是resolved。你在success中return Promise.reject只是让success回调函数本身返回了一个被拒绝的 Promise,但这并不会影响已经处于resolved状态的原始 Promisep。因此,returnValue里的p.then依然会正常进入成功回调,catch自然也就监听不到。3. 正确的实现方式
如果你希望在请求成功但业务状态码异常时,让外部的
catch能够捕获到错误,应该在returnValue中重新包装 Promise,并在其中进行判断和主动reject。参考以下示例代码(适用于 Vue3 项目):
4. 注意事项
catch拿不到报错信息;Vue3 则调用成功进入then,失败进入catch。请根据你的项目类型调整returnValue中的处理逻辑。returnValue接收到的参数可能不是 Promise,而是 XMLHttpRequest 对象,直接修改其属性可能会提示只读。如果是微信小程序,可能需要通过args.onHeadersReceived来获取状态码并进行分流处理。具体实现需根据目标平台进行条件编译和适配。参考文档:
要回复问题请先登录或注册
公告
更多>相关问题