await Promise调用后返回undefined?附代码及Vue.js生命周期场景
为什么await调用wxreq后返回undefined?
嘿,我来帮你拆解下这个问题——你遇到的await wxreq后返回undefined的情况,核心问题出在Promise的resolve时机和回调执行顺序上,咱们一步步分析:
核心问题:complete回调提前触发了Promise的resolve
你的wxreq函数里,wepy.request的complete回调中调用了resolve(),这是关键bug:
wepy.request的回调执行顺序是:success/fail执行过程中(或完成后),会立刻触发complete回调。- 而你的
success是async函数,里面有await res的异步操作——当代码执行到await res时,success函数会暂停执行,把线程让出去,这时候complete回调会先执行,直接调用resolve()把外层Promise的状态设为resolved,值是undefined。 - 等
await res完成后,再调用resolve(responseFromMiddle.data)已经没用了,因为Promise的状态一旦确定就再也无法改变,所以最终你await wxreq得到的就是undefined。
次要问题:success回调的async/await可能存在误区
你注释里说res是一个Promise,但通常wepy.request的success回调参数是直接的响应对象,不是Promise。如果res真的是Promise,那await res没问题;但如果不是,await res只是返回res本身,这部分逻辑可以再确认下,但这不是导致返回undefined的主因。
修复方案
只需要移除complete回调里的resolve(),让Promise只在success或fail里完成状态变更就好:
export const wxreq = (config) => { config.url = `${HTTP_HOST}${config.url}`; return new Promise((resolve, reject) => { wepy.request(Object.assign(config, { async success (res) { // 如果res确实是Promise,await它;否则直接使用res const responseFromMiddle = await res; resolve(responseFromMiddle.data); }, fail () { reject(new Error(`Request ${config.url} fail!`)); }, complete () { // complete只用来做清理类操作(比如隐藏loading),不要调用resolve/reject } })) }); };
优化建议:简化Promise封装
你还可以把wxreq改成async函数,避免手动嵌套Promise,代码会更清晰:
export const wxreq = async (config) => { config.url = `${HTTP_HOST}${config.url}`; // 先把wepy.request转成Promise形式 const res = await new Promise((resolve, reject) => { wepy.request(Object.assign(config, { success: resolve, fail: () => reject(new Error(`Request ${config.url} fail!`)) })); }); // 在这里处理res的await逻辑 const responseFromMiddle = await res; return responseFromMiddle.data; };
这样代码结构更直观,也不容易出现回调顺序导致的问题。
内容的提问来源于stack exchange,提问作者lumersgo
相关产品推荐
相关产品推荐

