简体   繁体   English

为什么它是以下代码中的竞争条件?

[英]Why is it a race condition in the following code?

I have the following code ES Lint marks as a race condition:我将以下代码 ES Lint 标记为竞争条件:

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

Full error:完整错误:

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

If I change "person.id" to something unrelated to person object like "null", the error vanishes.如果我将“person.id”更改为与“null”之类的人 object 无关的内容,错误就会消失。 What is the problem here and how to avoid it?这里有什么问题以及如何避免它? (I mean fix code if it's a real race condition problem or tell the linter that it's not a problem if not). (我的意思是修复代码,如果它是一个真正的竞争条件问题,或者告诉 linter,如果不是,这不是问题)。

This code could be problematic if you called fillPersonPositions more than once, and the id of the person changed in the meantime.如果您多次调用fillPersonPositions并且此人的id在此期间更改,则此代码可能会出现问题。 Eg:例如:

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

Here, there's no guarantee that the first fillPersonPositions resolves first, so at the end, you might end up with person having an ID of 3, but a positions property corresponding to the ID of 1.在这里,不能保证第一个fillPersonPositions会首先解析,所以最后你可能会得到一个 ID 为 3 的person ,但它的positions属性对应于 ID 1。

Of course, the above is very contrived, but ESLint does not know that.当然,上面说的很做作,但是 ESLint 并不知道。

One possible fix would be to avoid mutation, and instead return (and use) a new object:一种可能的解决方法是避免突变,而是返回(并使用)新的 object:

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

(It's often a good idea to avoid mutation when possible anyway, for the sake of more understandable code - for similar reasons, const is a better choice than let when you have the option) (无论如何,为了更易于理解的代码,尽可能避免突变通常是一个好主意 - 出于类似的原因,当您有选择权时, const是比let更好的选择)

The code is marked because person is not atomic because it theoretically could be changed elsewehre during your asynchronous opertation.标记代码是因为person不是原子的,因为理论上它可以在异步操作期间进行更改。

You can turn of this rule by changing the following entry within your .eslintrc.json file:您可以通过更改.eslintrc.json文件中的以下条目来关闭此规则:

"require-atomic-updates": "off"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM