Async/await is constructed in order to give a clean syntax to the continuation semantics of asynchronous operations. With other words to avoid callback / promise hell.
async function is a keyword, and the returned value or the thrown error is wrapped into a promise.
await is an operator that 'waits' for the promise to be resolved and returns the value resolved by the promise or throws the error it was rejected with then continues execution. Note that it does not block the JS thread.
Generators can have similar syntax but more verbose and rely on third party coroutine libraries.
My preference is async/await. It is supported by the major web browsers and Node.js. Can be transpiled to ES5.