useAtomicUpdates (JavaScript)
Summary
Section titled “Summary”- Diagnostic Category:
lint/nursery/useAtomicUpdates - This rule doesn’t have a fix.
- The default severity of this rule is information.
- Sources:
- Inspired from
require-atomic-updates
- Inspired from
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "useAtomicUpdates": "error" } } }}Description
Section titled “Description”Disallow assignments that can be based on outdated values because of await or yield.
A function pauses at every await and yield, and other code can run
during the pause. If the function reads a variable, pauses, and then
assigns a new value computed from what it read before the pause, the
assignment can undo a change that other code made in the meantime.
let total = 0;
async function addToTotal(getAmount) { // `total` is read here, before `getAmount()` finishes. total += await getAmount();}
// Both calls read `total` while it's still 0, so one of the amounts is lost.await Promise.all([addToTotal(getFirstAmount), addToTotal(getSecondAmount)]);code-block.js:5:5 lint/nursery/useAtomicUpdates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ total may be reassigned based on an outdated value of total.
3 │ async function addToTotal(getAmount) {
4 │ // `total` is read here, before `getAmount()` finishes.
> 5 │ total += await getAmount();
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^
6 │ }
7 │
ℹ This function reads total, then pauses at an await or yield before this assignment. Other code can change total during the pause, and this assignment would overwrite that change.
ℹ Store the result of the await or yield in a local variable first, then read total and assign the new value without pausing in between.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
The rule also reports assignments to properties of objects that other code can access, such as parameters and variables declared outside of the function.
Variables that are declared inside the function and aren’t used by any
other function are ignored, because no other code can change them.
Variables that aren’t declared in the file, such as window or process,
are ignored too.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”let total = 0;
async function addToTotal(getAmount) { total = total + await getAmount();}code-block.js:4:5 lint/nursery/useAtomicUpdates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ total may be reassigned based on an outdated value of total.
3 │ async function addToTotal(getAmount) {
> 4 │ total = total + await getAmount();
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 │ }
6 │
ℹ This function reads total, then pauses at an await or yield before this assignment. Other code can change total during the pause, and this assignment would overwrite that change.
ℹ Store the result of the await or yield in a local variable first, then read total and assign the new value without pausing in between.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
let count = 0;
async function refresh() { const previous = count; await reload(); count = previous + 1;}code-block.js:6:5 lint/nursery/useAtomicUpdates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ count may be reassigned based on an outdated value of count.
4 │ const previous = count;
5 │ await reload();
> 6 │ count = previous + 1;
│ ^^^^^^^^^^^^^^^^^^^^
7 │ }
8 │
ℹ This function reads count, then pauses at an await or yield before this assignment. Other code can change count during the pause, and this assignment would overwrite that change.
ℹ Store the result of the await or yield in a local variable first, then read count and assign the new value without pausing in between.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
async function addBonus(player) { player.score += await fetchBonus();}code-block.js:2:5 lint/nursery/useAtomicUpdates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ player.score may be assigned based on an outdated state of player.
1 │ async function addBonus(player) {
> 2 │ player.score += await fetchBonus();
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 │ }
4 │
ℹ This function reads player, then pauses at an await or yield before this assignment. Other code can change player during the pause, and this assignment would overwrite that change.
ℹ Store the result of the await or yield in a local variable first, then read player and assign the new value without pausing in between.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
let ids = [];
function* collect() { ids = ids.concat(yield);}code-block.js:4:5 lint/nursery/useAtomicUpdates ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ ids may be reassigned based on an outdated value of ids.
3 │ function* collect() {
> 4 │ ids = ids.concat(yield);
│ ^^^^^^^^^^^^^^^^^^^^^^^
5 │ }
6 │
ℹ This function reads ids, then pauses at an await or yield before this assignment. Other code can change ids during the pause, and this assignment would overwrite that change.
ℹ Store the result of the await or yield in a local variable first, then read ids and assign the new value without pausing in between.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
let total = 0;
async function addToTotal(getAmount) { const amount = await getAmount(); total += amount;}
async function sum(getAmount) { let localTotal = 0; localTotal += await getAmount(); return localTotal;}
async function addBonus(player) { const bonus = await fetchBonus(); player.score += bonus;}Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.