try/catch 语句中异步函数的执行上下文流程

问题描述 投票:0回答:3

    async function foo() {
    try {
      const response = await fetch("https://www.xxx.xxx");
      const data = await response.json();
      console.log(data);
    } catch (e) {
        console.log("Error!!: ", e);
      }
    }
    foo();
    console.log('111');

假设有这样一段代码,执行结果是

111 -> 错误:类型错误:无法获取

这就是当我考虑执行上下文过程时发生的情况,具体取决于代码流程

  1. 当调用 foo 函数时,会创建 foo 函数的执行上下文并添加到调用堆栈中。

  2. 当 fetch("https://www.xxx.xxx ") 在 try 块内运行时,会创建 fetch 函数的执行上下文并将其添加到调用堆栈中。这是在后台发出网络请求的时间。 fetch 函数返回一个 Promise,并且 fetch 函数的执行上下文将从调用堆栈中删除。

  3. await 关键字之后的后续操作将添加到微任务队列中。

  4. foo 函数结束,从调用堆栈中删除 foo 函数的执行上下文。

  5. 执行console.log('111),控制台输出“111”。

  6. 由于调用栈为空,所以在await之后的后续在微任务队列中排队的操作会依次移至调用栈并执行。

  7. fetch函数的网络请求失败,调用了reject,导致Promise的状态为rejected。

  8. 如何捕获错误???

try/catch 语句有点令人困惑。

为了让console.log('111)运行,调用栈必须为空,但是已经结束的foo函数中的catch怎么会出错呢??

请帮助我!

javascript asynchronous async-await promise try-catch
3个回答
0
投票

我想这可能会帮助你理解:

  • 您在没有等待的情况下调用 foo() 函数,因此它会生成一个 对 foo 函数和方法 foo() 的异步调用将是 挂起直到获取函数(等待的任务)返回响应。
  • 到那时它将执行下一条语句。所以 111 将被记录在控制台中。
  • 当 fetch 方法返回错误时,它将在控制台中打印错误。
  • 如果您想要同步日志,请在 foo() 之前使用await。所以 main 方法将挂起,直到 foo() 返回一些响应。由于 foo 中的 fetch 返回错误,它将打印错误,然后将打印 111

0
投票

由于您的

foo()
是异步的,因此
await
之后的所有内容都是异步执行的,因此在
console.log('111')
之后是同步的。所以使用
await foo()
等待
foo()
解决后再解决
console.log('111')
:

async function foo() {
    try {
      const response = await fetch("https://www.xxx.xxx");
      const data = await response.json();
      console.log(data);
    } catch (e) {
        console.log("Error!!: ", e);
      }
    }
(async() => {
    await foo();
    console.log('111');
})();


-1
投票

也许这几点可以帮助你:

  1. console.log(111)
    foo()
    承诺完成之前被调用。
  2. 要捕获
    foo()
    抛出的错误,您需要添加
    .catch(err => ...)
  3. 如果想从外部捕获异常,则需要在catch子句中抛出异常,(或者不尝试捕获)

注意,您可以在调用 foo 之前添加

await
,以便在之后进行顺序调用,因此 console.log(111) 将在 Promise 完成后被调用

© www.soinside.com 2019 - 2024. All rights reserved.