【问题标题】:Why is it possible to reassign `const x` in the console after an await?为什么可以在等待后在控制台中重新分配“const x”?
【发布时间】:2020-02-09 17:21:37
【问题描述】:

编辑:我发现你甚至不需要这个功能。这也适用于我:

const x = await 'hello'
x = 'something else'

请注意,如果没有 await,它会引发错误。

首先定义一个异步函数,

async function a() {
  return new Promise(resolve => {
    resolve('hello')
  })
}

然后将x分配给'hello'

const x = await a()

然后重新分配x

x = 'something else'

如果x是一个常量变量,为什么可以重新赋值呢?我这里有什么明显的遗漏吗?

这是完整的代码(在 Chrome 80.0.3987.87 的浏览器控制台中测试):

async function a() {
  return new Promise(resolve => {
    resolve('hello')
  })
}

const x = await a()

x = 'something else'

【问题讨论】:

  • 您确实没有发布足够的代码来给出答案;无法重新分配普通的 const 符号。
  • 随着您的更新,您的问题似乎是关于 chrome 开发者控制台和顶级等待的怪癖。普通代码不会那样做。
  • 看起来几乎像 REPL 的错误以及顶级等待。注意:在 REPL 中拆分代码,我可以在 chrome 和 FF 上重现它,但不能在节点上重现(顶级 await 可能会引发错误,可能是因为我的节点版本是 12.10.0 而不是最新的)
  • const x = await 'hello' x = 'something else' 这让我更崩溃了...... :(

标签: javascript async-await google-chrome-devtools constants


【解决方案1】:

我无法重现您所描述的内容。它会给我一个错误。

async function a() {
  return new Promise(resolve => {
    resolve('hello')
  })
}

(async () => {
  try {
    const x = await a();
    x = 'something else';
    console.log("worked", x);
  } catch (err) {
    console.log("didn't work", err.toString());
  }
})()

根据您更新的问题,我发现当您在 chrome 开发人员控制台中输入代码时会发生这种情况。此外,您的代码在异步函数之外使用 await 。顶级 await 还不是 javascript 标准的一部分,尽管它正在以 through the approval process 的方式工作。开发工具确实允许您这样做,但如果结果的行为是非标准的,我不会感到惊讶。

【讨论】:

  • top-level-await 提案仅适用于模块,不会对 devtools 控制台中的await 产生任何影响。
  • 是的。这意味着我更不知道开发工具用它做什么:)
  • 嗯,有趣。我从来不知道顶级等待。
【解决方案2】:

更新:我能够在 Firefox 72.0.2(64 位)中重现该错误, 但是,如果你将它包装在 async 函数中,它的行为就不会那样......

了解更多信息:ECMAScript proposal: Top-level await

您可以等待字符串,因为它是允许的:block-await-expr-literal-string.js, AwaitExpression StringLiteral(顶级等待的有效语法 堵塞。) 因此const x = await ''; 是有效的语法

(async () => {
    async function a() {
        return new Promise(resolve => {
            resolve('hello')
        })
    }

    const x = await a()

    x = 'something else'

})();

嗯,可能你缺少控制台调试器..

async function a() {
  return new Promise(resolve => {
    resolve('hello')
  })
}

const x = await a()

x = 'something else'
x = 'not assignable... in console or whatever..';

【讨论】:

  • 这很奇怪,我的控制台上没有任何错误。 i.imgur.com/aF7jTxJ.png
  • 当我将三个sn-ps作为单独的语句输入时,我也可以重现,而不是一次全部。
  • 另外,将其包装在一个块中({…})即可触发异常
【解决方案3】:

您不应该在同步函数中使用 await 关键字(您的 func 是全局范围)。 这没有意义。我们正在使用 await 来等待 ex 的一些异步操作。 API 调用。

如果你删除 await 它通常会抛出一个错误。

【讨论】:

    【解决方案4】:

    首先请大家在学习这些东西的时候不要把浏览器控制台作为理想的编辑环境。

    其次,我刚刚检查了您在浏览器控制台中提到的内容。

    如果您只是简单地复制并粘贴整个代码,一旦出现预期的错误,即无法重新分配常量。正如@some用户的回答中明确提到的那样。

    但如果你逐行复制并粘贴它不会给你任何错误。

    我不确定是什么原因,但您不能指望浏览器控制台为您提供 100% 的编译器/验证环境。

    因此,除非是一些简单的表达式评估,否则最好使用良好的开发环境,这样您就不会被意外行为所迷惑。

    如果你仍然需要在浏览器上运行的东西,试试这个 http://www.typescriptlang.org/play/

    编辑:我在@Nicholas Tower 的回答中找到了这条评论,这似乎是这个问题的正确答案

    "top-level-await 提案只针对模块,它不会有任何 对 devtools 控制台中的 await 的影响。 ——贝尔吉”

    编码愉快!!!

    【讨论】:

      猜你喜欢
      • 2019-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 2014-11-12
      相关资源
      最近更新 更多