UNPKG

mini-scheduler

Version:

A mini scheduler for task handler in browser

7 lines (6 loc) 2.3 kB
/*! * mini-scheduler v1.0.0 * (c) 2021 bryce * @license MIT */ const e=e=>{let t;switch(e){case"setTimeout":t=window.setTimeout;break;case"requestAnimationFrame":t=window.requestAnimationFrame;break;default:throw new Error("currently only support 'setTimeout' | 'requestAnimationFrame' types")}return t},t=()=>performance.now(),n=(e,t)=>{let n=e.pop();for(;e.length&&n;)t(n),n=e.pop()},o=Promise.resolve(),r=e=>o.then(e),i=e=>!!e&&e.toString().includes("Generator"),s=[];let u=!1,a=60,c=10,m=window.setTimeout;const w=[],l=e=>navigator?.scheduling?.isInputPending()||t()<e+1e3/a-c,d=e=>{const o=()=>{const r=t();let i=null;do{i=e.next()}while(!i.done&&l(r));if(i.done){const e=m===window.setTimeout?window.clearTimeout:window.cancelAnimationFrame;return void n(w,e)}const s=m(o);w.push(s)};return o};const f=()=>{const e=function*(){for(let e=0;e<s.length;e++){const t=(0,s[e])();if(i(t)){const e=m(d(t));w.push(e)}else yield t}s.length=0,u=!1}();return function o(){const r=t();let i=null;do{i=e.next()}while(!i.done&&l(r));if(i.done){const e=m===window.setTimeout?window.clearTimeout:window.cancelAnimationFrame;return void n(w,e)}const s=m(o);w.push(s)}},p=e=>{const{fps:t=60,renderTime:n=10,funcType:o="setTimeout"}=e;if(a<=0||a>120)throw new Error(`fps must between 0~120, instead of ${a}`);if(c<=0||c>=1e3/60)throw new Error(`fps must between 0~${Math.floor(1e3/60)}, instead of ${c} ms`);if(!["setTimeout","requestAnimationFrame"].includes(o))throw new TypeError("funcType must be window.setTimeout or window.requestAnimationFrame");a=t,c=n,m="setTimeout"===o?window.setTimeout:window.requestAnimationFrame},h=(e,t,n={fps:60,renderTime:10,funcType:"setTimeout"})=>{p(n);for(let n=0;n<e.length;n++)o=()=>t(e[n],n,e),s.includes(o)||s.push(o),u||(u=!0,r(f()));var o},T=(e,t={fps:60,renderTime:10,funcType:"setTimeout"})=>{if(!i(e))throw new TypeError("payload func must be a generator ");p(t);const n=m(d(e));w.push(n)},y=async(e,t,n)=>{const o=[],r=[];for(const i of t){const s=Promise.resolve().then((()=>n(i,t)));if(o.push(s),e<=t.length){const t=s.then((()=>r.splice(r.indexOf(t),1)));r.push(t),r.length>=e&&await Promise.race(r)}}return await Promise.all(o)};export{y as asyncPool,n as clearTimers,e as getAsyncFunc,t as getTime,i as isGenerator,r as nextTick,h as ts,T as tsGenerator};