Skip to content

Instantly share code, notes, and snippets.

@atellmer
Created August 20, 2022 16:37
Show Gist options
  • Save atellmer/034ff9ef6574ba02b216d1c62bc28c55 to your computer and use it in GitHub Desktop.
Save atellmer/034ff9ef6574ba02b216d1c62bc28c55 to your computer and use it in GitHub Desktop.
Worker with blocking worker thread
<!DOCTYPE html>
<html>
<head>
<title>Worker</title>
<meta charset="UTF-8" />
<style>
#element {
width: 200px;
height: 100px;
background-color: blueviolet;
}
</style>
</head>
<body>
<div id='element'></div>
<script src="./index.js"></script>
</body>
</html>
const worker = new Worker("worker.js");
const buffer = new SharedArrayBuffer(4);
const scope = new Int32Array(buffer);
worker.postMessage(scope);
worker.onmessage = function (e) {
const data = e.data;
if (detectIsAction(data) && data.type === I_NEED_DOM_RECT) {
console.log('main thread receive message from worker:', data);
const element = document.querySelector(data.selector);
const rect = element.getBoundingClientRect();
unblockThread();
console.log('✅ unblock worker thread!');
worker.postMessage({
type: DOM_RECT,
selector: data.selector,
value: rect,
});
}
};
function unblockThread() {
scope[0] = 0;
}
function detectIsAction(data) {
return typeof data === 'object' && data && data.type;
}
const I_NEED_DOM_RECT = 'I_NEED_DOM_RECT';
const DOM_RECT = 'DOM_RECT';
let scope = null;
self.onmessage = function (e) {
const data = e.data;
if (data instanceof Int32Array) {
scope = data;
}
if (detectIsAction(data) && data.type === DOM_RECT) {
console.log('calculated rect:', e.data);
}
};
function getDOMRect(selector) {
blockThread();
console.log('⛔️ block worker thread!');
isMessageSent = false;
while (detectIsThreadBlocked()) {
console.log('loop while worker thread blocked...');
if (!isMessageSent) {
self.postMessage({
type: I_NEED_DOM_RECT,
selector,
});
}
isMessageSent = true;
}
}
function detectIsThreadBlocked() {
return scope[0] === 1;
}
function blockThread() {
scope[0] = 1;
}
function detectIsAction(data) {
return typeof data === 'object' && data && data.type;
}
const I_NEED_DOM_RECT = 'I_NEED_DOM_RECT';
const DOM_RECT = 'DOM_RECT';
// Test
setTimeout(() => {
console.log('getDOMRect!');
getDOMRect('#element');
}, 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment