> For the complete documentation index, see [llms.txt](https://notes.lirenxn.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes.lirenxn.com/2020/notes-03-15-concurrent-with-requestidlecallback.md).

# Notes-03-15-Concurrent-with-requestIdleCallback

#### Concurrent Basic <a href="#concurrent-basic" id="concurrent-basic"></a>

```javascript
let nextUnitOfWork = null

function workLoop(deadline) {
  let shouldYield = false
  while (nextUnitOfWork && !shouldYield) {
    nextUnitOfWork = performUnitOfWork(
      nextUnitOfWork
    )
    shouldYield = deadline.timeRemaining() < 1
  }
  requestIdleCallback(workLoop)
}

requestIdleCallback(workLoop)

function performUnitOfWork(nextUnitOfWork) {
  // return nextUnitOfWork
}
```

**Key Concept**

**window\.requestIdleCallback:**

Similar to `window.requestAnimationFrame`.

Pass a `deadline` object to the callback, which contains a `timeRemaining()` to calculate

**shim(just a shim, not polyfill):**

```javascript
window.cancelIdleCallback =
  window.requestIdleCallback ||
  function (cb) {
    const start = new Date();
    
    return setTimeout(function (){
      cb({
        didTimeout: false,
        timeRemaining: function(){
          const delta = new Date() - start;
          return Math.max(0, 50 - delta);
        }
      });
    }, 1);
  }

window.cancelIdleCallback =
  window.cancelIdleCallback ||
  function (id) {
    clearTimeout(id);
  }
```

**Key:**

1. Use `setTimeout` to put `callback` to the end of main loop/thread, as a macro task, so that it is able to check the `timeRemain` after main loop
2. Return timeRemain ONLY when it's less than 50 ms, quoted as **"When trying to maintain a responsive application, all responses to user interactions should be kept under 100ms. Should the user interact the 50ms window should, in most cases, allow for the idle callback to complete, and for the browser to respond to the user’s interactions."**
3. Function returns `id` of `setTimeout`, as a common pattern in JS event loop task handling, for program to call `cancelIdleCallback` upon, this is used to just trying mocking the js schedule ability
4. Quote: **"Ideally the work you do should be in small chunks (microtasks) that have relatively predictable characteristics." (nextUnitOfWork)**

**Ref:**

{% embed url="<https://developers.google.com/web/updates/2015/08/using-requestidlecallback>" %}

<https://pomb.us/build-your-own-react/>

[**https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback**](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)
