asynciterator
Version:
An asynchronous iterator library for advanced object pipelines.
35 lines (34 loc) • 1.33 kB
JavaScript
const resolved = Promise.resolve(undefined);
// Returns a function that asynchronously schedules a task
export function createTaskScheduler() {
// Use or create a microtask scheduler
const scheduleMicrotask = typeof queueMicrotask === 'function' ?
queueMicrotask : (task) => resolved.then(task);
// Use or create a macrotask scheduler
const scheduleMacrotask = typeof setImmediate === 'function' ?
setImmediate : (task) => setTimeout(task, 0);
// Interrupt with a macrotask every once in a while to avoid freezing
let i = 0;
let queue = null;
return (task) => {
// Tasks are currently being queued to avoid freezing
if (queue !== null)
queue.push(task);
// Tasks are being scheduled normally as microtasks
else if (++i < 100)
scheduleMicrotask(task);
// A macrotask interruption is needed
else {
// Hold all tasks in a queue, and reschedule them after a macrotask
queue = [task];
scheduleMacrotask(() => {
// Work through the queue
for (const queued of queue)
scheduleMicrotask(queued);
queue = null;
// Reset the interruption schedule
i = 0;
});
}
};
}