javascript - 调用另一个 block 中定义的异步函数的 UnhandledPromiseRejectionWarning

标签 javascript

{
  async function f() {
    return 1;
  }
}

(async () => {
  await f();
})();

请注意 f 在单独的 block 中。

当 f 不是异步函数时没关系。 但是使用异步函数,我收到错误 UnhandledPromiseRejectionWarning: ReferenceError: f is not defined

为什么异步函数不同?

最佳答案

好的,我在那儿:我已经解决了。

首先,严格模式是有区别的(见the MDN documentation)。在严格模式下,两者的行为是等价的:

"use strict";

{
  function f() {
    return 1;
  }
}

(async () => {
  console.log(await f());
})();

"use strict";

{
  async function f() {
    return 1;
  }
}

(async () => {
  console.log(await f());
})();

在 ES2015 之前, block 中的函数实际上在严格模式下是完全禁止的,但现在以预期的方式运行。

在 sloppy 模式下, block 中的函数在技术上是规范不允许的,但实际上是所有实现都允许的 (MDN vaguely explains this)。令人困惑的是,该函数被提升到最近的函数范围。这不是直观的行为,这就是它在严格模式下被更改的原因。

让事情变得更加困惑的是,sloppy 模式下的异步函数的作用域是 block ,即使普通函数的作用域是该函数。我没有找到任何记录此行为的内容。

{
  console.log(g()); // works
  console.log(f()); // works
  async function f() {
    return 1;
  }
  function g() {
    return 2;
  }
}

(async () => {
  console.log(await g()); // works
  console.log(await f()); //errors
})();

因此,由于为确保与旧代码的兼容性而做出的决定,在 sloppy 模式下情况很困惑。当然,这是在草率模式下开发时经常要避免的,这就是为什么您应该始终使用严格模式

感谢您提出一个非常有趣的问题!

关于javascript - 调用另一个 block 中定义的异步函数的 UnhandledPromiseRejectionWarning,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56068566/

相关文章:

javascript - 检测 Div 的可见宽度

javascript - 如何使用 ES5 Object.create 和对象字面量语法模拟构造函数?

javascript - 将 Raphael JS 在 Canvas 中生成的 SVG 保存为 png 时出现问题

javascript - Angular-Formly:隐藏/禁用服务中的字段

javascript - 总是在大括号后面加分号是一个坏主意吗?

javascript - Bootstrap 弹出窗口不保存复选框

javascript - 如何使用 gatsby-image 在不裁剪的情况下显示图像?

javascript - setToken 不会在 Google API (gapi) 中切换 YouTube channel

javascript - 如何显示表单 - 使用 jQuery、javascript 或 Meteor js 每次只显示一个输入字段?

javascript - 为什么 'join' 比正常连接更快?