queueTask

by jib1

HTML

<div id="div" style="white-space: pre;"></div>

JavaScript

const console = { log: msg => div.innerHTML += msg + "<br>" };
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));

function queueTask(f) {
  window.addEventListener("message", f, {once: true});
  window.postMessage("hi", window.origin);
}

const ms = 200;

(async () => {
  try {
    await wait(0);
    let stop = false;
    const p = wait(ms);
    let tasks1 = 0, tasks2 = 0;
    const base = performance.now();
    (async () => {
      while (!stop) {
        await new Promise(queueTask);
        tasks1++;
      }
    })();
    (async () => {
      while (!stop) {
        await wait(0);
        tasks2++;
      }
    })();
    await p;
    stop = true;
    const time = performance.now() - base;
    console.log(`Over ${time} ms:`);
    console.log("");
    console.log(`${tasks1} postMessage tasks / setTimeout(${ms}ms)`);
    console.log(`${(tasks1 / time).toFixed(2)} postMessage tasks / ms`);
    console.log(`postMessage takes = ${(time / tasks1).toFixed(2)} ms`);
    console.log("");
    console.log(`${tasks2} setTimeout(0) tasks / setTimeout(${ms}ms)`);
    console.log(`${(tasks2 / time).toFixed(2)} setTimeout(0) tasks / ms`);
    console.log(`setTimeout(0) takes = ${(time / tasks2).toFixed(2)} ms`);
    console.log("");
    console.log(`postMessage is ${((time / tasks2) / (time / tasks1)).toFixed(2)} times more frequent than setTimeout(0)`);
  } catch(e) {
    console.log(e);
  }
})();