Redundant await
ID |
javascript.redundant_await |
Severity |
low |
Remediation Complexity |
auto_fix |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
JavaScript |
Tags |
performance, reliability |
Description
Reports await applied where it cannot meaningfully suspend execution. Two cases are flagged:
-
await await expr— the innerawaitalready resolves the value to its non-thenable form; the outerawaitadds an extra microtask hop and nothing else. -
await <literal>where the literal is a primitive (number, string, boolean,null, regex), array literal, object literal, or template literal. Awaiting a non-thenable simply schedules a microtask before continuing — pure overhead and noise.
The rule does not flag await x when x could be a promise (any non-literal expression). A real promise type cannot be inferred without flow / type analysis.
Rationale
-
await await xis almost always a typo or a leftover from a refactor (the firstawaitwas added then forgotten when wrapping happened later). It pays a microtask round-trip every call. -
await 1works — the engine wraps the value withPromise.resolve— but it costs a microtask and the reader has to stop and ask "is1actually a promise here?". Using the literal directly is clearer.
// Bad
const u = await await fetchUser();
const x = await 1;
const tpl = await `${name}-${id}`;
Remediation
Drop the redundant await:
// Good
const u = await fetchUser();
const x = 1;
const tpl = `${name}-${id}`;