Suggest an editImprove this articleRefine the answer for “await in arrow functions”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**Yes, `await` works inside an arrow function, but only if that arrow is declared as `async`.** `await` is an operator allowed only inside an `async` function or at the top level of an ES module (top-level await). An arrow function is nothing special here: `async () => {}` produces the same kind of asynchronous function as `async function`, and it always returns a promise, even when there is no `await` in the body. Without the `async` keyword the engine will not even start running the code: it fails at parse time with `SyntaxError: await is only valid in async functions`. It is equally legal to write an `async` arrow as a callback, for example inside `.then()` or `map()`. ```javascript const fetchData = async () => { const data = await Promise.resolve('Done'); console.log(data); // Done }; ``` **Key point:** it is `async`, not the arrow syntax, that enables `await`; an `async` arrow always returns a promise.Shown above the full answer for quick recall.Answer (EN)Image**Yes, you can use `await` inside an arrow function, but only when that arrow is declared with the `async` keyword.** The shape of the function is irrelevant here: it is `async` that grants permission to use `await`, not the arrow or the `function` keyword. ## Theory ### TL;DR - `await` is allowed only inside an `async` function or at the top level of an ES module. - An arrow function becomes asynchronous just as easily: `async () => { ... }`. - Without `async` you get a `SyntaxError`, and the code does not run at all, because the error happens at parse time. - Any `async` function, arrow ones included, always returns a promise. - An `async` arrow can be passed as a callback, for example into `.then()`, and `await` inside it is perfectly legal. - Outside a function, `await` works only as top-level await in ESM. ### Quick example ```javascript const fetchData = async () => { const data = await Promise.resolve('Done'); console.log(data); }; fetchData(); ``` Result: ```text Done ``` `async` in front of an arrow function turns it into an asynchronous function that always returns a promise. ### Where await is allowed at all `await` is an operator you may use in exactly two places: - inside a function declared with `async`; - at the top level of a module (top-level await). Using `await` outside `async` is a syntax error: ```javascript // Error const result = await Promise.resolve(42); // SyntaxError: await is only valid in async functions ``` The same goes for a plain arrow without `async`: ```javascript const foo = () => { const data = await Promise.resolve('value'); console.log(data); }; // SyntaxError: await is only valid in async functions ``` Note that this is not a runtime error. JS will not even start executing the code, because `await` is not permitted in a normal function, so the script fails while it is still being parsed. ### What an async arrow returns An `async` arrow always returns a promise, even when it contains no `await` at all: ```javascript const sum = async (a, b) => a + b; console.log(sum(1, 2)); // Promise { 3 } ``` That is the same as writing: ```javascript function sum(a, b) { return Promise.resolve(a + b); } ``` So the result of such a function has to be either awaited or handled through `.then()`. ### Different ways to write it An arrow with `await` in its plain form: ```javascript const loadUser = async () => { const res = await fetch('/api/user'); return res.json(); }; ``` With parameters: ```javascript const getUser = async (id) => { const res = await fetch(`/api/user/${id}`); return res.json(); }; ``` A multi-line form: ```javascript const processData = async () => { const data = await fetch('/api/data'); const json = await data.json(); console.log(json); }; ``` Inside a promise chain: ```javascript Promise.resolve('A') .then(async (x) => { const y = await Promise.resolve('B'); return x + y; }) .then(console.log); // "AB" ``` Here `then()` takes an async arrow function and `await` inside it is entirely legal: `then` simply waits for the promise that this function returns. ### Top-level await Modern JS modules (ESM) let you use `await` outside functions, as long as the code really runs as a module and not as a plain `<script>` without `type="module"`: ```javascript // main.js const data = await fetch('/api/data').then(r => r.json()); console.log(data); ``` This is top-level await. It works only in ESM (in the browser with `<script type="module">`, or in Node.js with `"type": "module"` in `package.json`). In a CommonJS module such code will not run. > A simple analogy: `async` in front of an arrow function is a pass that gives you the right to use `await` inside. Without it the engine simply does not know where to deliver the awaited result. ### Summary table | Question | Answer | | --- | --- | | Can `await` be used in an arrow function? | Yes, if it is declared as `async` | | What happens without `async`? | `SyntaxError: await is only valid in async functions` | | What does an `async` arrow return? | Always a `Promise` | | Can `await` appear in `.then()` or in callbacks? | Yes, if the callback itself is declared `async` | | Can `await` be used outside a function? | Only as top-level await in modules | ### Common mistakes - Putting `await` in a plain arrow and being surprised that even the code before it does not run: this is a parse error, not a runtime one. - Forgetting that an `async` arrow returns a promise and writing `const x = sum(1, 2)`, which yields a `Promise` instead of a number. - Marking the outer function `async` while using `await` inside a nested plain callback, for example `arr.forEach(item => { await save(item); })`. The callback itself is what needs the keyword: `async item => ...`. - Expecting `arr.forEach(async ...)` to wait for every operation: `forEach` ignores the returned promises, so you need `for...of` with `await` or `Promise.all(arr.map(async ...))`. - Using top-level await in a file that is loaded as a classic script or as CommonJS, where it is simply not available.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.