Skip to content

Instantly share code, notes, and snippets.

@gngenius02
Created July 4, 2021 18:11
Show Gist options
  • Save gngenius02/317b50451f0dcb9efd48d733e01c0066 to your computer and use it in GitHub Desktop.
Save gngenius02/317b50451f0dcb9efd48d733e01c0066 to your computer and use it in GitHub Desktop.
replace settimeout with a worker version that works in the background. even when tab is out of focus. This is not tested across browsers. just works on chromium based browsers.
;(function (exports) {
let tid = 0
const timers = new Map()
const jsblob = `
const timers = new Map()
const runTimer = function (id) {
this.postMessage({ id })
timers.delete(id)
}
this.addEventListener('message', (evt) => {
let { id, command, timeout } = evt.data
switch (command) {
case 'setTimeout':
timers.set(id, { id, command, timeout })
setTimeout(runTimer.bind(null, id), timeout | 0)
break
case 'clearTimeout':
if (timers.has(id)) clearTimeout(timers.get(id).id)
timers.delete(id)
break
}
})
`
const blob = new Blob([jsblob], { type: 'application/javascript' })
const workerURL = URL.createObjectURL(blob)
const worker = new Worker(workerURL)
const oldSetTimeout = setTimeout
const oldClearTimeout = clearTimeout
worker.addEventListener('message', function (evt) {
const { id } = evt.data
const { fn, args } = timers.get(id)
fn.apply(null, args)
timers.delete(id)
})
exports.setTimeout = function (fn, timeout = 0) {
const args = [...arguments].slice(2)
timers.set(++tid, { fn, args })
worker.postMessage({ command: 'setTimeout', id: tid, timeout })
return tid
}
exports.clearTimeout = function (id) {
worker.postMessage({ command: 'clearTimeout', id })
timers.delete(id)
}
})(typeof window !== 'undefined' ? window : typeof globalThis !== 'undefined' ? globalThis : {})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment