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.
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
async awaitis 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.
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:
- Detect when the scroll thumb reaches the bottom of the container.
- Maintain the state of
offsetand fetch the next set of items.
- Synchronization of API calls over the network, the response will come out of order often.
First, we will setup a source for us. We will just create a mock web-service which returns numbers given an
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:
init method creates the eventIterator on the
container with the condition of the scoll thumb reaching the bottom. And in a loop:
- Gets the next set of items, waits until they are received.
- Appends the items to the container
- Wait for the next emission of the conditional event stream.
You can see the full source, with the working Fiddle.