Javascript Generator Yield/Next vs Async-Await Overview and Comparison | by Deepak Gupta | Towards Data Science

Functions that can return multiple values at different time interval, as per the user demands and can manage its internal state are generator functions. A function becomes a GeneratorFunction if it uses the function* syntax.
They are different from normal functions in the sense that normal function run to completion in a single execution whereas generator function can be paused and resumed, so they do run to completion but the trigger remains in the developer’s hand. They allow better execution control for asynchronous functionality but that does not mean they cannot be used as synchronous functionality.
Note: When generator function are executed it returns a new Generator object.
The pause and resume are done using yield & next. So let's look at what are they and what they do.
The yield keyword pauses generator function execution and the value of the expression following the yield keyword is returned to the generator's caller. It can be thought of as a generator-based version of the return keyword.
The yield keyword actually returns an IteratorResult object with two properties, value and done. (If you don’t know what are iterators and iterables then read here).
Once paused on a yield expression, the generator's code execution remains paused until the generator's next() method is called. Each time the generator's next() method is called, the generator resumes execution and returns the iterator result.
Pheww... enough of theory, let's see an example
function* UUIDGenerator() {    let d, r;    while(true) {        yield 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {            r = (new Date().getTime() + Math.random()*16)%16 | 0;            d = Math.floor(d/16);            return (c=='x' ? r : (r&0x3|0x8)).toString(16);        });    }};
Here, UUIDGenerator is a generator function which calculates the UUID using current time on a random number and returns a new UUID every time it is executed.
To run the above function we need to create a generator object on which we can call next()
const UUID = UUIDGenerator();// UUID is our generator objectUUID.next() // return {value: 'e35834ae-8694-4e16-8352-6d2368b3ccbf', done: false}
UUID.next() will return you the new UUID on each UUID.next() under the value key and done will always be false as we are in an infinite loop.
Note: We pause above the infinite loop, which is kind of cool and at any “stopping points” in a generator function, not only can they yield values to an external function, but they also can receive values from outside.
There is a lot of practical implementation of generators as one above and a lot of libraries that heavily use it, co, koa, and redux-saga are some examples.
Traditionally, callbacks were passed and invoked when an asynchronous operation returned with data which are handled using a Promise.
Async/Await is a special syntax to work with promises in a more comfortable fashion which is surprisingly easy to understand and use.
The async keyword is used to define an asynchronous function, which returns a AsyncFunction object.
The await keyword is used to pause async function execution until a Promise is fulfilled, that is resolved or rejected, and to resume execution of the async function after fulfillment. When resumed, the value of the await the expression is that of the fulfilled Promise.
Key points:
1. await can only be used inside an async function.
2. Functions with the async keyword will always return a promise.
3. Multiple awaits will always run in sequential order under the same function.
4. If a promise resolves normally, then await promise returns the result. But in case of a rejection, it throws the error just as if there were a throw statement at that line.
5. An async function cannot wait for multiple promises at the same time.
6. Performance issues can occur if using many await as one statement doesn’t depend on the previous one.
So far so good, now let us see a simple example:
async function asyncFunction() {  const promise = new Promise((resolve, reject) => {    setTimeout(() => resolve("i am resolved!"), 1000)  });  const result = await promise;   // wait till the promise resolves (*)  console.log(result); // "i am resolved!"}asyncFunction();
The asyncFunction execution “pauses” at the line await promise and resumes when the promise settles, with result becoming its result. So the code above shows “i am resolved!” in one second.
Generator functions/yield and Async functions/await can both be used to write asynchronous code that “waits”, which means code that looks as if it was synchronous, even though it really is asynchronous.A generator function is executed yield by yield i.e one yield-expression at a time by its iterator (the next method) whereas async-await, they are executed sequential await by await.Async/await makes it easier to implement a particular use case of Generators.The return value of the generator is always {value: X, done: Boolean} whereas for async functions, it will always be a promise that will either resolve to the value X or throw an error.An async function can be decomposed into a generator and promise implementation which is good to know stuff.
Generator functions/yield and Async functions/await can both be used to write asynchronous code that “waits”, which means code that looks as if it was synchronous, even though it really is asynchronous.
A generator function is executed yield by yield i.e one yield-expression at a time by its iterator (the next method) whereas async-await, they are executed sequential await by await.
Async/await makes it easier to implement a particular use case of Generators.
The return value of the generator is always {value: X, done: Boolean} whereas for async functions, it will always be a promise that will either resolve to the value X or throw an error.
An async function can be decomposed into a generator and promise implementation which is good to know stuff.
Please consider entering your email here if you’d like to be added to my email list and follow me on medium to read more article on javascript and on github to see my crazy code. If anything is not clear or you want to point out something, please comment down below.
You may also like my other articles
Javascript Execution Context and HoistingUnderstanding Javascript ‘this’ keyword (Context).Javascript data structure with map, reduce, filterJavascript- Currying VS Partial ApplicationJavascript ES6 — Iterables and IteratorsJavascript — Proxy , Javascript — Scopes
Javascript Execution Context and Hoisting
Understanding Javascript ‘this’ keyword (Context).
Javascript data structure with map, reduce, filter
Javascript- Currying VS Partial Application
Javascript ES6 — Iterables and Iterators
Javascript — Proxy , Javascript — Scopes
If you liked the article, feel free to share and help others find it!