Last active
May 19, 2019 12:29
-
-
Save IUnknown68/8041a9ef25ef8609607f22cb1ca6ac22 to your computer and use it in GitHub Desktop.
Cooperative multitasking for javascript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function multiTasking(schedule = setTimeout) { | |
const taskList = new Set(); | |
let isRunning = false; | |
let isScheduled = false; | |
const next = () => { | |
isScheduled = false; | |
taskList.forEach(task => { | |
if (!isRunning) { | |
return; | |
} | |
if (task.next().done) { | |
remove(task); | |
} | |
}); | |
if (isRunning && taskList.size) { | |
run(); | |
} else { | |
stop(); | |
} | |
}; | |
const run = () => { | |
if (!isScheduled) { | |
isScheduled = true; | |
console.log('scheduling'); | |
schedule(next); | |
} | |
} | |
const start = () => { | |
if (!isRunning) { | |
isRunning = true; | |
console.log('starting'); | |
run(); | |
} | |
}; | |
const stop = () => { | |
console.log('stopped'); | |
isRunning = false; | |
}; | |
const add = (...tasks) => { | |
tasks.forEach(task => { | |
taskList.add(task); | |
start(); | |
}); | |
return tasks.length > 1 ? tasks : tasks[0]; | |
}; | |
const remove = (...tasks) => { | |
tasks.forEach(task => { | |
taskList.delete(task); | |
}); | |
}; | |
const clear = () => { | |
taskList.clear(); | |
}; | |
return { | |
start, | |
stop, | |
add, | |
remove, | |
clear | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Each task needs to be a generator function that yields control back to the task manager (cooperative multitasking):
You can pass a custom scheduler function, e.g. one that runs always one second after the last run: