首页 > 解决方案 > 为什么等待后的布尔赋值会触发原子更新错误?

问题描述

let searching = false;

const search = async () => {
  if (searching) {
    throw new Error('No parallel process allowed.');
  }
  try {
    searching = true;
    const result = await someAsyncMethod();
    searching = false;
    return result;
  } catch (e) {
    searching = false;
    throw e;
  }
};

上面的代码会在第 10 行vscode说“可能的竞争条件:searching可能会根据过时的值重新分配”时生成原子更新错误。searchingsearching = false

为什么?它真的会造成数据竞赛吗?

标签: node.jseslint

解决方案


ESLint 不够聪明,无法识别searching变量的重要性。违反规则的条件

  • 变量或属性被重新分配给基于其旧值的新值。
  • 在读取旧值之后、设置新值之前,yield 或 await 表达式会中断赋值。
  • 该规则不能轻易地验证分配是否安全(例如,如果分配的变量是本地的并且在函数暂停时无法从其他任何地方读取)。

ESLint 看到的逻辑类似于:“如果调用函数时搜索为假,则在异步方法之后重新分配搜索。” await这是警告,在调用函数之后,但在解决之前,其他东西可能已将 search 重新分配为 true ,在这种情况下,在之后重新分配await将基于过时的值执行某些操作,这可能是不可取的。

以下代码没有searching = true引发相同的警告:

let searching = false;

const search = async () => {
  if (searching) {
    throw new Error('No parallel process allowed.');
  }
  try {
    const result = await someAsyncMethod();
    searching = false;
    return result;
  } catch (e) {
    searching = false;
    throw e;
  }
};

尽管您的逻辑是合理的,但 ESLint 无法确定您的确切意图。随意在此处禁用该规则。


推荐阅读