javascript react

Let's first get familiar with generator, generator is special type of function which you can pause and resume at will. Here is a simple generaor

Simple Generator Function


            function* getNumers() {
                yield 1;
                yield 2;
                yield 3;
            }
          
            const iterator = getNumers();
            //This does nothing, as the generator is not stared yet, we have to star it by calling .next
            iterator.next(); // output {value: 1, done: false}
            iterator.next(); // output {value: 2, done: false}
            iterator.next(); // output {value: 3, done: true};
            iterator.next(); // output {value: undefined, done: true}
            /*
            As you can see, generator doesn't just return the
            value, it returns a special kind of object with
            value on it, once the final value is yielded then
            done becomes true and value becomes undefined on
            subsequent runs.
            */
          
          

This is not very useful, but later we will see, how we can use generators to simplify our ajax calls.

Making ajax request has always been tricky in JavaScript. JavaScript is a single threaded language, so we don't want to pause the event loop when we make ajax requests, to solve this previously we used the callback pattern. Though It solved the problem, from time to time we would end up with callback hell.The introduction of Promises solved this to some extent, but sometimes Promise is not enough when we want to make several nested ajax requests, we can end up with Pyramid of doom. Let's explore an example -

Using Promises

 
            function getGithubFollowers(userName) {
                return ajax(`https://api.github.com/users/${userName}`)
                .then(response => {
                const { followers_url } = response
                return ajax(followers_url)
                })
            }
          
            const followers = getGithubFollowers('azs06')
            console.log(followers)
          

This is a very simple example, but we might end up in a situation where we have to make several ajax calls to get the information we need to make another server call, then things could get messy and we could end up with pyramid of doom. We can use generators and coroutine to make it more elegent and avoid pyramid of doom.

Using Generators and Coroutine


           const bluebird = require('bluebird')

           function* getGithubFollowers(userName) {
              const user = yield ajax(`https://api.github.com/users/${userName}`)
              const { followers_url } = user
              const followers = yield ajax(followers_url)
              return followers;
            }
            
           const ajaxRoutine = bluebird.coroutine(getGithubFollowers)
            
           ajaxRoutine('azs06').catch(error => console.log(error)).then((response) => console.log(response))
            

As you can see, from the look of it, it's much more easier to read and reason with.

I know for this simpler example this seems a overkill, but for a larger application with houndreds of server calls this can do wonders.

You can also get similar ajax request flow by using async await, Which is built on top of generators.

Using Async Await


           async function getGithubFollowers(userName) {
                const user = await ajax(`https://api.github.com/users/${userName}`)
                const { followers_url } = user
                const followers = await ajax(followers_url)
                return followers;
          }
              
           getGithubFollowers('azs06').then(response => console.log(response))
          
          

This seems a better choice, considering we don't have to use another library(coroutine), but learning and using generators will help you understand how async await working underneath. Also you can't pause and pass parameter at the middle of async await function, which you can do with generators. The power of generator is that you can pause it and resume it at will. This opens up opportunity to use generator many more creative ways.

To Learn more about Generators -

  1. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
  2. https://davidwalsh.name/es6-generators
  3. https://richardartoul.github.io/javascript/2015/07/16/promises-generators.html
  4. https://x.st/javascript-coroutines/
  5. Generators in JavaScript by Fun Fun Function
  6. Generator by Kyle Robinson Young