js同步代码中没有执行try/catch代码?

let isRefreshToken = false
const request = (url:string, method:string, data?:any) => {
  return new Promise(async (resolve, reject) => {
    if (isRefreshToken) return
    // 判断token超时,刷新token
    if (Store.getters.expiresTime && new Date().getTime() >= Store.getters.expiresTime) {
      await refreshData()
      return
    }
    ...
}

const refreshData = async () => {
  if (!isRefreshToken) {
    isRefreshToken = true
    if (!Store.getters.referToken) {
      cleanData()
      isRefreshToken = false
    } else {
      console.log(123);
      try {
        let res = await refreshToken(Store.getters.referToken) 
        Store.dispatch('SaveInfo', res)  
        isRefreshToken = false  
        uni.switchTab({ url: '/pages/device/index' })
      } catch (error) {
        cleanData()
      }
      console.log(333);
    }
  }
}

打印结果:
打印走到了else中,输出了123。但是没有走trycatch代码?不知道是什么原因?
image.png

阅读 1.2k
avatarAI BotBETA

根据你提供的代码,try/catch 代码块确实存在,并且应该被执行。如果控制流走到了 else 分支,并且输出了 123,那么 try/catch 代码块应该会执行。

如果你发现 try/catch 代码块没有被执行,可能是由于以下几个原因:

  1. 语法错误: 确保你的代码中没有语法错误,例如拼写错误、缺少分号等。这些错误可能导致代码无法正确解析和执行。
  2. 条件判断问题: 在你的代码中,if (!isRefreshToken) 判断条件可能会阻止 try/catch 代码块的执行。如果 isRefreshToken 的值为 true,那么 refreshData 函数中的代码将不会执行,因此也不会执行 try/catch 代码块。确保 isRefreshToken 的值在调用 refreshData 函数时是 false
  3. 异步操作问题: 你的代码中使用了异步操作,例如 await refreshToken(Store.getters.referToken)。异步操作可能导致代码的执行顺序不是你预期的那样。确保异步操作已经正确处理,并且没有导致意外的行为。
  4. 控制台输出问题: 在你的代码中,console.log(123);console.log(333); 被放在了不同的位置。如果 try/catch 代码块中的代码没有执行,那么控制台可能只输出了 333,而没有输出 123。检查控制台输出以确保正确执行了相关代码。

如果你能提供更多关于问题的详细信息,例如错误消息、控制台输出等,我将能够更好地帮助你解决问题。

3 个回答

通常情况下不会在 new Promise() 里用 async 函数。如果想用 await,可以不用 new Promise() 直接把外层函数定义为 async 函数,比如

const request = async (url: string, method: string, data?: any) => {
//              ^^^^^ 声明为 async 函数
    if (isRefreshToken) return
    // 判断token超时,刷新token
    if (Store.getters.expiresTime && new Date().getTime() >= Store.getters.expiresTime) {
        await refreshData()
//      ^^^^^^^^^^^^^^^^^^^ 这里如果发生错误,会 reject 穿透出去
        return
    }
}

既然用的 TypeScript,会发现 request 的返回类型是 Promise<unknown>,和 return new Promise(...) 的返回类型是一致的。如果确实要用 Promise 对象,应该这样

let isRefreshToken = false
const request = (url: string, method: string, data?: any): Promise<unknown> => {
    return new Promise((resolve, reject) => {
//                     ^^^ 不要 async,内部也不要用 await(不赞成 await 和回调混用)
        if (isRefreshToken) return
        // 判断token超时,刷新token
        if (Store.getters.expiresTime && new Date().getTime() >= Store.getters.expiresTime) {
            refreshData().then(resolve, reject);
//                       ^^^^^^^^^^^^^^^^^^^^^^ 将 refreshData 的运行和 resolve, reject 绑定起来
            return
        }
    });
}

const refreshData = async () => { }

所以两种方式,一种是直接定义 async 函数,另一种是在 new Promise() 里正确调用 resolve 和 reject。

顺便说一下,这不是“同步”,是异步。就算是用 await,也是异步程序的“同步写法”,而不是同步。

如果你的 refreshToken 是这种货色:

function refreshToken(){
  return new Promise((resolve, reject) => {
    // 既不 resolve, 也不 reject,哎!就是玩
  })
}
或者其中出现类似的逻辑,也就是既不resolve,也不 reject
那么对于refreshToken而言:
  • 由于 Promise 从未 resolve,所以 await 不到任何值;
  • 另外 Promise 不会 reject,因此 catch 不到任何错误。

所以问题出在refreshToken(及其所在的调用栈),多半是某个地方出错了又不 reject 所致。


好吧,看你的request中就出现了光return而不调用 resolve的错误写法,那么可以肯定这是一个错误习惯了,对应改掉就行。

我通过代码分析也应该是refreshToken异步函数没有返回值。可以看上面request函数,使用了promise但有多处return标记,promise构造函数内部的状态没有得到改变,一直处于pedding状态。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Microsoft
子站问答
访问
宣传栏