Asynchronous pagination using generators 1/2
Published: 2023-11-27 12:44:33

For documentation about generators look here [Generators]([JSINFO](https://javascript.info/generators))

Here is a way to accomplish asynchrounous paging using generators

```js

const data = [...Array(400)].map((_,i) => `${i + 1}`);
const itemsPerPage = 10;
const next = "next";
const prev = "prev";
const forward = 1;
const backward = -1;
const nbPages =  Math.ceil(data.length/itemsPerPage) ;
const click = "click";

let pagination;
let currentPage = 1;

const delay = (ms) => {
  return new Promise ((res, err) => {
    setTimeout(res, ms) 
  })
}

async function fetchData (start, end) {
  await delay(0)
  return await  data.slice(start, end);
}

async function* paginate(data, itemsPerPage) {
    let index = 0;
    const stepindex = (dir) => index += dir * itemsPerPage;
    while (true) {
        const direction = yield ;
        if (direction === next) {
            stepindex(forward);
        } else if (direction === prev) {
            stepindex(backward);
        }
        yield await fetchData(index, index + itemsPerPage);
    }
}

async function nextItems () {
  let res = (await pagination.next(next)).value; 
  pagination.next()
  return res;
}  
 
async function prevtItems () {
  let res =  (await pagination.next(prev)).value;
  pagination.next()
  return res;  
}   

function limitSup () {
  return currentPage == nbPages;
}

function limitInf () {
  return currentPage == 1;
}

function renderView (pageItems) {
  if (typeof(pageItems) != typeof([]))  { 
    alert("too fast")
    return;
  }
  page.innerText = `${currentPage}/${nbPages}`
  results.innerHTML = `
    <table border='0' width="20%">
      <tr><td>Items n°</td><td>value</td></tr>
      ${pageItems.map(it => `
        <tr>
          <td style='padding:1rem'>${it}</td>
          <td>data-${it}</td>
        </tr>`).join('')} 
    </table>
  ` 
}

document.getElementById(next).addEventListener(click, async () => {
  if (limitSup()) return;
  currentPage = Math.min(++currentPage, nbPages)
  renderView (await nextItems())
})

document.getElementById(prev).addEventListener(click, async () => {
  if (limitInf ()) return;
  currentPage = Math.max(--currentPage, 1)
  renderView (await prevtItems())
})


function main () {
  renderView(data.slice(0, itemsPerPage))
  pagination = paginate(data, itemsPerPage);
  pagination.next();
}

main ()

```
You can play with the demo here [Demo](https://flems.io/#0=N4IgtglgJlA2CmIBcB2AHAOgMwE4A0IAxgPYB2AzsQskVbAIYAO58UIB5hATncgNoAGPAIC6BAGYQE5fqFL0wiJCAwALAC5hY7WqXXw9NADqkTJgDxQIANwAE0ALxGQXeOQCusdeWcA+E7a2FgD0Vtb+pqSWNrbk6gCeCE4gVuSMDPFI4ggAHgDcAFbucRDi8QC0JHoG6khp9ITw5fQ87qRQfgG20eFdAAr0AObwtkjd9aT2UMmMQ-B+5sETEYHmAEbu6upkUzOu1p2Ttn0ASgCiAGohG1tkERY325OOzqTwOeqHgQByZwAaABVrpsnhFFmF7pFwTYIjoWAhCOoIGQZMoUEhcCAAL54OQKJQqAoyAhVfSGZRVOK2KD0dT0WwOWx8DAsgCCXC49HiAAoACwCAQAShEGDATG53IA+ngIIKGb5bAADAAkwAgtgA1LYAIxYxWCvImSnqez6MDkPrwLgDYYMnUCQ2kY22N4fO2vd6fECO52MfbukB++AHb1GlEm8TELgAdxaUDt2p94dsawaAGtY1x44zyomwxQTaQ1ja3HbbABZWmqDCNKTcml0jAIUiDdSqYIQM0Wq0luVJgu2QiwCCENMBocjtPOR0mBAm2aDCDyJFkR1zwfuDk1EsJmdO5NQeAZO3c81yhwK4BdVzqTeTN7R448SAsWwS1zkPC2K1cc+XrqBCw6gAhAijEJs3Ifl+Z5BEcWKCiYWJmPI5DxE6tjiG0iLIpM4jwOohCqAAIrS9LcnELTqF+BhQHKV5HPQsadtSR5ctyQrXvhd62Ix9DMdSpEYOQw6NORdJcFR37tAaiHIfQqHoZhTorqQABUtgLkutLwPWpFfp28Dmpa1pzHRAG2OuS6HjkdoOuZzpxPAjBWe8J5WL+8r2O0rkaoy7m2OpBlGT2cyOoEgTRqoUgjNy6hcO48BmUc4Xhc67nwNhOyMvEEBHvGYUpeFpRvulmWTA4FUup6SWFbVsT6M53k5NykYxnGMnJYVWLfrAr7FfWECuGVDKVUG1g1XVKWOY11ncqmo6ZrRBW1UhnUpTleU8UxEb4YRJF0tyLk5PpTWaqahndiZwwdSlq2rSY8loYQGFYSpVUfAAkl2b4TeuH4nrxzGacuOEYK66jcuDgqChg1j0LACV5LBgTA7SoPg9yCFHDe3Efo63XIw9CnPUpw1jeoX0XT9tj0YEf2loyb6A-OQxaSpYOetyY3Q7D8OI10qPsxjWOBDjXCTHjgSIeFyGk29w6QOoADK7iMNTtO2GLkyEJurh6DulVFiW5D47Lr04RZoGdh9pDiOrnG3uLG5bvrcwjTqpuRHLFt64eXAXLlj5c3MlMwRr-UJIw8DEOIwfDKH5BygAhIykfR7HfAiNDgTAMj4Xw1aEPONsxAYfJXoi+FWsFatKNzBgS5vFwAKenaKrADrLvqCWWLBKqRtzOQeqcR4XjkA3pBNwAEgC5YADJt+Z5h0msCAplGfsOAA5AIW+2NG0BtskABMAgAKRfIVy9cL4y9QL4CcugADYs6j33fvhwwj8Cv+-wRxSsQqqoFzwATqKcUzELxKnMila+gDJp33qokeA29ZgwCXIMJA2pXBgC3r4VUnYsS-3gXVD+DZ6DlAIeoIh-974wPCq-G++oMAFGIEubkW8t6Cm6kvf+9BV7wEAYqWC912jEB1ooPQGBhjqDOAgSR6gABC8QPpQEhtVDA9AYBnGsDUOeEBHJN25BOUcX5HroUxp5cOdtuQK07CrRgmM5TVy6J3PW3c3aMkrG2UU7CNQajcduOYX4B7DETpxby-tA5M22u9CmXYnGISxiYKA4j3AKOkfhORhkajKNUVzfYMMtFQB0XogxZIrTGJEmmMxxNqZQOsW+OxFNbY-WcVxcWBVAmu1tF4qs4DmrlEqLrIJwwvzakrr7K0Ad4BB2ZhpfY8SLqJNIPBZCJhvY7DFEue22MaLTMDrpRswkRw6SEOdYKV1EqV0FhbRkgsdLkP0l2YyvYCq3LIBzD4mNPYmG2ZMTG6zIgmDhEeDKKlUQgBwAANiQAIcoAg4XYlxCAeQigaA1nIMSXQZJ1A0DWMQKA8QaauKoFGMYhB4j0FIAVeaaZBitHaKMFMDBRxI1kpEFea8NZii4IuUg5QCW3DAMy4+OD8agoRBCmgsLj5YGxGIVF+IaDmOeh80g2IgA)