首页 > 解决方案 > 为什么它是以下代码中的竞争条件?

问题描述

我将以下代码 ES Lint 标记为竞争条件:

const fillPersonPositions = async (person) => {
    person.positions = await getPositions(person.id);
};

完整错误:

Possible race condition: `person.positions` might be reassigned based on an outdated value of `person.positions`.eslint(require-atomic-updates)

如果我将“person.id”更改为与“null”之类的人对象无关的内容,错误就会消失。这里有什么问题以及如何避免它?(我的意思是修复代码,如果它是一个真正的竞争条件问题,或者告诉 linter,如果不是,这不是问题)。

标签: javascriptasynchronousasync-awaiteslint

解决方案


如果您fillPersonPositions多次调用此代码可能会出现问题,并且此id人的身份同时发生了变化。例如:

person.id = 1;
const p1 = fillPersonPositions(person);
person.id = 3;
const p2 = fillPersonPositions(person);
await Promise.all([p1, p2]);

在这里,不能保证第一个首先fillPersonPositions解析,所以最后,您可能会person得到一个 ID 为 3 的属性,但positions属性对应于 ID 1。

当然,上面说的很做作,但是 ESLint 并不知道。

一种可能的解决方法是避免突变,而是返回(并使用)一个新对象:

const fillPersonPositions = async (person) => {
    const positions = await getPositions(person.id);
    return { ...person, positions };
};

(无论如何,为了更易于理解的代码,尽可能避免突变通常是一个好主意 - 出于类似的原因,const这是一个比let你有选择权时更好的选择)


推荐阅读