Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

It doesn’t work for callback-based async (including native Promises, but some libraries like Bluebird can help). But it does work for suspending async functions (native async/await, generators)! This also applies to Error#stack and debugger call stacks.

I’m actively moving some projects I inherited from Promise APIs to async/await for this reason.




What is the difference between promises and native async/await? From the perspective of coding them they seem to be exactly the same.

It preserves the call stack as soon as you use ‘await’ instead of ‘[promise].then’?


Native async/await functions use generator functions under the hood, which are an implementation of coroutines. Like all fully-fledged coroutine implementations, generators can suspend execution while preserving the stack by yielding control (hence the `yield` keyword). This requires interpreter (e.g. V8) support.

Desuguared Promise.then can't suspend the stack like that as a normal JS thread must run to completion and cannot yield to the scheduler; instead every call to `.then` pushes the new closure onto the event/microtask queue.


The difference is that an async function suspends on await, and continues to be active in the call stack until it returns. It doesn’t preserve the stack so much as continues to be on the stack. A Promise-returning function returns the Promise value synchronously and then/catch/etc continue from a new stack where they’re resolved.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: