# require-atomic-updates

> Disallow assignments that use a value read before an `await` or a `yield`

`total += await fetchPrice(id)` reads `total` first, then waits. If two calls run at the same time, both start from the same `total`, and one of the additions is lost.

The rule checks async functions and generators. It reports an assignment to a variable or a property that was read before an `await` or a `yield` and not read again after it. A local variable that no other function uses isn't reported, because nothing else can change it during the wait.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"require-atomic-updates" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"require-atomic-updates" = ["error", {
  allowProperties = false,
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad */}
```js
let total = 0;

async function addPrice(id) {
  total += await fetchPrice(id);
}
```

Not reported:

{/* good */}
```js
let total = 0;

async function addPrice(id) {
  const price = await fetchPrice(id);
  total += price;
}

async function sumPrices(ids) {
  let sum = 0;
  for (const id of ids) {
    sum += await fetchPrice(id);
  }
  return sum;
}
```

A property of a parameter is checked too, because the caller still holds the object:

{/* bad */}
```js
async function loadUser(session) {
  if (!session.user) {
    session.user = await fetchUser(session.id);
  }
}
```

Check again after the wait:

{/* good */}
```js
async function loadUser(session) {
  const user = await fetchUser(session.id);
  if (!session.user) {
    session.user = user;
  }
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `allowProperties` | `false` | Don't report assignments to properties. Variables are still checked. |

{/* good {"options": [{"allowProperties": true}]} */}
```js
async function loadUser(session) {
  if (!session.user) {
    session.user = await fetchUser(session.id);
  }
}
```

## When not to use it

The rule can't tell whether two calls ever overlap, so it also reports code where nothing else touches the value. If most reports are about properties of request or context objects, set `allowProperties` to `true`.
