UnhandledPromiseRejectionWarning调用另一个块中定义的异步函数

时间:2019-05-09 22:51:32

标签: javascript

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

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

请注意,f位于单独的块中。

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

为什么异步功能不同?

1 个答案:

答案 0 :(得分:1)

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

首先,严格模式之间有所区别(请参见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之前,严格禁止在严格模式下使用块中的功能,但现在它们的行为符合预期。

在草率模式下,规范上不允许使用块中的功能,但实际上所有实现(MDN vaguely explains this)都允许使用块中的功能。令人困惑的是,该功能被提升到最近的功能范围。这不是直观的行为,这就是为什么在严格模式下更改它的原因。

为了使事情更加混乱,即使普通函数将范围限定在该函数上,草率模式下的异步函数也将限定于该块。我还没有发现任何可以证明这种行为的东西。

{
  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
})();

因此,由于为确保与旧代码的兼容性而做出的决定,在草率模式下情况令人困惑。当然,这是在草率模式下进行时会不断避免的原因,这就是为什么您应该始终使用严格模式的原因。

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