🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 8 Min Lesezeit
0

Advanced JS Execution: Promises, Workers, and Comlink

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

You wrap a slow loop in an async function. You await a Promise. You expect the page to stay smooth.



Instead the tab freezes. Scroll stops. Clicks queue up. The spinner never moves.



Promises did not break. They solved a different problem than the one you had.




Promises help you wait. They do not move CPU work off the main thread. Web Workers do.




This article builds that idea in order:




  1. Why async still freezes the UI

  2. How a worker fixes it with postMessage

  3. How Comlink, SharedArrayBuffer, and worker pools fit when the app grows



We reuse one example the whole way: crunch a large array of numbers (think pixels or analytics rows) without locking the page.






Runnable examples (this GitHub repo)



Every major step has a small project you can clone and run. They live in for install commands.




























Example Folder What you learn
Frozen UI
postMessage keeps UI responsive
Comlink Comlink + SharedArrayBuffer + COOP/COEP
Browser pool Piscina on Node worker_threads





CODE
git clone https://github.com/mrajaeim/Advanced-JS-Execution.git
cd Advanced-JS-Execution/examples/02-raw-web-worker
npm install
npm run dev






The snippets below are shortened for reading. Prefer the GitHub projects when you want the full UI (status text, Ping button, Vite setup).









The Problem



Many developers assume:




If the code uses async / await / Promises, the UI stays smooth.




That is only true for waiting (network, timers, disk). It is false for computing on the main thread.




CODE
async function processOnMainThread(numbers) {
await Promise.resolve(); // yields once, then...

let total = 0;
for (let i = 0; i < numbers.length; i++) {
total += Math.sqrt(numbers[i] * numbers[i] + 1);
}
return total; // ...this still owns the main thread
}

button.addEventListener('click', async () => {
status.textContent = 'Working...';
const numbers = Array.from({ length: 8_000_000 }, (_, i) => i);
const total = await processOnMainThread(numbers);
status.textContent = `Done: ${total}`;
});






Expected: status updates, page stays clickable, then "Done".



Actual: UI freezes until the loop finishes. Try it in .



worker.js




CODE
self.onmessage = (event) => {
const numbers = event.data;
let total = 0;
for (let i = 0; i < numbers.length; i++) {
total += Math.sqrt(numbers[i] * numbers[i] + 1);
}
self.postMessage(total);
};






main.js




CODE
function processInWorker(numbers) {
return new Promise((resolve, reject) => {
const worker = new Worker(new URL('./worker.js', import.meta.url));

worker.onmessage = (event) => {
resolve(event.data);
worker.terminate();
};
worker.onerror = (error) => {
reject(error);
worker.terminate();
};

worker.postMessage(numbers);
});
}

button.addEventListener('click', async () => {
status.textContent = 'Working...';
const numbers = Array.from({ length: 8_000_000 }, (_, i) => i);
const total = await processInWorker(numbers);
status.textContent = `Done: ${total}`;
});






Expected: "Working..." stays visible, Ping UI keeps counting, then "Done" appears.






What each piece does




























Piece Role
new Worker(...) Starts a second JS thread (no DOM access)
postMessage(numbers) Sends a clone of the data; main continues immediately
Worker's onmessage
Runs the loop on the worker stack

processInWorker's Promise
Only waits for the reply, does not run the math





CODE
MAIN                                   WORKER
click → status = "Working..."
postMessage(numbers) ───────────────► receive array
await (main free for clicks) run loop
onmessage ←────────────────────────── postMessage(total)
status = "Done..."






Chunking the loop with setTimeout(0) on the main thread can soften small freezes. For large jobs it gets messy (progress, cancellation, slower total time). A worker is the clearer architecture.









Next Step: Comlink (RPC-style Workers)



Raw postMessage turns into a homemade protocol (type, payload, request IDs, error shapes). That gets noisy when the worker has many methods.



.



Worker




CODE
import { expose } from 'comlink';

function calculate(numbers) {
let total = 0;
for (let i = 0; i < numbers.length; i++) {
total += Math.sqrt(numbers[i] * numbers[i] + 1);
}
return total;
}

expose({ calculate });






Main




CODE
import { wrap } from 'comlink';

const worker = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module',
});
const api = wrap(worker);

const total = await api.calculate(numbers);


























Style Call site Who routes replies
Raw postMessage
{ type, payload } You
Comlink await api.calculate(data) Comlink


Use raw messaging for one tiny job with zero dependencies. Use Comlink when the worker becomes a real API (image pipelines, inference helpers, multi-method tools).



Comlink also supports transferables, typed APIs, and SharedArrayBuffer-friendly flows.









When Copying Data Is the Bottleneck: SharedArrayBuffer



postMessage clones or transfers data. For huge frames or tensors shared by several workers, that traffic can dominate cost.



A SharedArrayBuffer is memory more than one thread can see at once. Workers mutate it in place. You still need careful partitioning or Atomics so threads do not corrupt each other.




CODE
Main (UI)
│ Comlink (start job / progress / done)
Worker pool
│ SharedArrayBuffer (pixels, tensors)
WASM / SIMD kernels






Runnable project (Vite sets COOP/COEP):



await worker.method() ergonomics in the browser



Production Node worker pool










Warnings Worth Knowing





  • No DOM in workers. Compute there, update React/DOM on the main thread.


  • Huge clones stall the main thread too. Prefer transferables for big ArrayBuffers: worker.postMessage(buffer, [buffer]).


  • Match worker type to how you load it (classic vs { type: 'module' }).


  • Wire worker.onerror (and pool errors) or failures look like hung Promises.


  • Browser Workers ≠ Node worker_threads. Same idea, different APIs and libraries.









When to Use What








































Situation Use
Waiting on network, timers, IndexedDB Promises / async
Short work between awaits Stay on the main thread
Large CPU work, UI must stay live Web Worker
Worker grows into many methods Comlink
Many concurrent jobs workerpool (browser) or Piscina (Node)
Huge shared frames/tensors SharedArrayBuffer after measuring
I/O-bound or tiny work Do not add a worker








Conclusion



async does not equal "runs in parallel." It equals "can wait without busy-waiting on this thread."



A Web Worker is the tool that runs heavy JavaScript somewhere else while the UI thread stays free. Wrap the reply in a Promise so your app code stays readable.



Then climb only as far as you need:




  1. Raw postMessage ()

  2. A pool ()

  3. SharedArrayBuffer (example 04) when memory movement is the bottleneck



Clone the repo, run 01 next to 02, and click Ping UI in both. That comparison teaches the architecture faster than any diagram.



What was the first job you tried to "fix" with async/await that still froze the tab?

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Advanced JS Execution: Promises, Workers, and Comlink

Thematisch verwandte Begriffe: Advanced, Execution, Promises, Workers · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...