Infinite Scroll using Generators!

Put ES6 generators to some real use.

Disclaimer: No JS libraries or frameworks were created or used while writing this article.

ES6 generators are awesome! .. says who ? Tech blogs, medium articles, developer videos, well anyone who wants to be cool.

What are generators ? Quoting MDN: “Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.” There are a number of articles written on this, I choose not to reinvent the wheel, and encourage you to read up about generators if you do not already know their physics.

Koa, redux-saga and a bunch of other libraries started using generators as first class citizens initially. With the aim of making Async code, read like synchronous code.

Things changed when async await came around. Koa moved to using them, they are a far more simpler construct to address the readability concerns traditional methods like Promises and callbacks have.

async await is a much simpler construct to make async code look sync.

But then what about generators ? They come in handy when we need to streamify a large input source. So, Infinite scroll.

How the final Infinite Scroll will look like
Infinite scrolling is a web-design technique that loads content continuously as the user scrolls down the page, eliminating the need for pagination.

An effective implementation of Infinite scroll involves:

  1. Detect when the scroll thumb reaches the bottom of the container.
  2. Maintain the state of offset and fetch the next set of items.
  3. Synchronization of API calls over the network, the response will come out of order often.

We will see how generators make this a breeze. Note: this article assumes basic understanding of how generators work in Javascript.

First, we will setup a source for us. We will just create a mock web-service which returns numbers given an offset and batchSize.

This simply returns a promise which resolves after a random delay with an array of numbers or content. We will streamify this service method, by wrapping it inside a generator.

This method just keeps on yielding the next set of results. Notice that the maintenance of offset state is encapsulated within the generator method.

Now, to get the events when the scroll reaches the bottom. We will create a generic event stream, which listens on an UI event and emits whenever the supplied condition is satisfied.

Here, we setup an eventListener on el for the name event. Whenever the event is fired we check the supplied condition and when satisfied we call the resolve method. The resolve method is nothing but a saved resolution callback from a Promise. We use the Promise property here that they can only be resolved once, thus multiple calling of resolve() method is a no-op, until a new promise is created.

Alright, if you are still with me you know how generators work! Now let me introduce the magic which will glue everything together and make shit work:

The init method creates the eventIterator on the container with the condition of the scoll thumb reaching the bottom. And in a loop:

  1. Gets the next set of items, waits until they are received.
  2. Appends the items to the container
  3. Wait for the next emission of the conditional event stream.

Done! Simple & Elegant. Pure native javascript.

You can see the full source, with the working Fiddle.