They could've shipped the `Promise` object with a `coroutine` fn, like bluebird did, and had the same semantics without needing to reserve words and add syntax to the language. All it opens up is combining async and generators, which can be handy for iterating things like prefetched results, but that's a rare enough case not to need to be baked into the language.
Separating the coroutine would let us work beyond just promises too. Wrap around old code using error-first callbacks, or new code using observables (yield to get the next, yield* to complete). I just wrote a coroutine to give quasi-concurrency to Google apps scripts, so it can queue up the routines running `fetch` methods and instead do them in one parallel-request-making `fetchAll`. It's a much better approach for the long-term of a language. Imho 90% of the junk we deal with in old languages is stuff for a convenient implementation at the time that we don't use anymore.