当前位置: 首页 > 知识库问答 >
问题:

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

通和裕
2024-02-25
let isRefreshToken = falseconst 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

共有4个答案

陈茂
2024-02-25

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

呼延宪
2024-02-25

如果你的 refreshToken 是这种货色:

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

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


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

钱震博
2024-02-25

通常情况下不会在 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 = falseconst 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,也是异步程序的“同步写法”,而不是同步。

诸修伟
2024-02-25

根据你提供的代码,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。检查控制台输出以确保正确执行了相关代码。

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

 类似资料:
  • 在测试同步代码时,省略回调,Mocha将自动继续进行下一次测试。 describe('Array', function() { describe('#indexOf()', function() { it('should return -1 when the value is not present', function() { [1,2,3].indexOf(5).should.eq

  • 问题内容: 我正在审查一些新代码。该程序仅具有try和finally块。由于不包含catch块,如果try块遇到异常或任何可抛出的异常,它将如何工作?它是否直接进入了finally块? 问题答案: 如果try块中的任何代码都可以引发已检查的异常,则它必须出现在方法签名的throws子句中。如果引发了未经检查的异常,则该异常会冒泡退出方法。 无论是否引发异常,都始终执行finally块。

  • 背景: React代码如下 setCount的更新是异步更新的,setTimeout也是异步的,为什么点击,console.log打印的是0,而不是1。 尝试: 尝试用普通js函数进行比较,js代码如下 console.log打印的是最新的值2。 疑问: 两段代码的打印结果不同,是什么原因呢?

  • 当我在阅读有关承诺的文章时,我知道当我使用async/Await时,我可以同步打印承诺(在本例中为print:first,second,third,last to print)。现在我也读到了使用链接和异步/等待也可以达到同样的目的。然而,当我试图将我的承诺链接起来时,除了“最后一次打印”的console.log之外,什么也没有发生。任何洞察力都会很棒!谢谢!! 编辑到问题: 日志: 1:如果传递

  • 我意识到这似乎是其他问题的重复,但我已经看了每一个建议的SO问题,我可以找到之前张贴,我正在寻找关于这个特定场景的帮助,因为没有其他答案对我有效。 我有一个Node/Express应用程序正在初始化一个MongoDB连接,以供REST API使用。第一步是连接到MongoDB实例。如果初始连接失败,它会像预期的那样抛出一个错误。我正在使用async/await和它内部的try/catch块来处理这

  • 问题内容: 我们正在与节点合作,主要用于内部项目,并了解使用该技术的最佳方法。 并非来自特定的异步背景,学习曲线可能是一个挑战,但是我们已经习惯了框架和学习过程。 使我们两极分化的是,何时才是使用同步代码与异步代码的最佳时间。我们目前使用的规则是,如果任何东西与IO进行交互,那么它必须通过回调或事件发射器(即给定的)是异步的,但是可以将任何未使用IO的其他项构造为同步函数(此方法还将取决于函数本身