Signatur
Beschreibung
Atomics.waitAsync() ist die asynchrone Variante von Atomics.wait(). Die Methode prüft atomar, ob an der Position index eines gemeinsam genutzten Int32Array oder BigInt64Array noch der Wert value steht. Ist das der Fall, wartet sie auf ein Atomics.notify() für diese Stelle oder auf das Ablaufen des Timeouts. Anders als Atomics.wait() blockiert sie den Thread nicht, sondern gibt sofort ein Objekt zurück, das bei Bedarf ein Promise enthält.
Deshalb lässt sich waitAsync() auch im Haupt-Thread des Browsers verwenden, wo Atomics.wait() verboten ist. Typische Einsatzfälle: Der UI-Thread wartet darauf, dass ein Worker eine Berechnung abgeschlossen hat, oder man baut Synchronisationsbausteine wie Mutexe, Semaphoren und Signale, die sich mit async/await nutzen lassen.
Der Rückgabewert ist ein Objekt { async, value }:
async: false: Das Ergebnis steht sofort fest.valueist"not-equal", wenn der Wert bereits abweicht, oder"timed-out", wenntimeoutgleich0ist.async: true:valueist einPromise. Es wird mit"ok"erfüllt, sobald eine Benachrichtigung eintrifft, oder mit"timed-out", wenn die Zeit abläuft.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $typedArray Pflicht | Int32Array | BigInt64Array | Ein Integer-Array, das auf einem SharedArrayBuffer liegt. Andere Typen oder ein normaler ArrayBuffer lösen einen TypeError aus. |
|
| $index Pflicht | number | Position im Array, an der gewartet wird. Liegt der Wert außerhalb des Arrays, wird ein RangeError ausgelöst. |
|
| $value Pflicht | number | bigint | Erwarteter Wert. Nur wenn die Speicherstelle genau diesen Wert enthält, wird gewartet. Bei BigInt64Array muss es ein bigint sein. |
|
| $timeout | number | Infinity | Maximale Wartezeit in Millisekunden. NaN wird als Infinity behandelt, negative Werte als 0. |
Rückgabewert
async: false) oder über ein Promise geliefert wird (async: true).Beispiele
Sofortige Ergebnisse: Wert weicht ab oder Timeout 0
const sab = new SharedArrayBuffer(16);
const int32 = new Int32Array(sab);
// An int32[0] steht 0, erwartet wird aber 42
console.log(Atomics.waitAsync(int32, 0, 42));
// Der Wert stimmt, aber das Timeout ist 0
console.log(Atomics.waitAsync(int32, 0, 0, 0));
Auf Benachrichtigung warten (mit async/await)
const int32 = new Int32Array(new SharedArrayBuffer(4));
const result = Atomics.waitAsync(int32, 0, 0, 1000);
console.log(result.async); // true
// Später, z. B. aus einem Worker oder per Timer:
setTimeout(() => {
Atomics.store(int32, 0, 1);
Atomics.notify(int32, 0);
}, 100);
const status = await result.value;
console.log(status, Atomics.load(int32, 0));
Haupt-Thread wartet auf einen Worker (Node.js)
// main.mjs
import { Worker } from 'node:worker_threads';
const int32 = new Int32Array(new SharedArrayBuffer(4));
const worker = new Worker(`
const { workerData } = require('node:worker_threads');
const flag = new Int32Array(workerData);
// aufwendige Arbeit simulieren
let sum = 0;
for (let i = 0; i < 1e8; i++) sum += i;
Atomics.store(flag, 0, 1);
Atomics.notify(flag, 0);
`, { eval: true, workerData: int32.buffer });
const waitForDone = async () => {
const { async, value } = Atomics.waitAsync(int32, 0, 0, 5000);
const status = async ? await value : value;
console.log('Worker-Status:', status);
await worker.terminate();
};
await waitForDone();
Hilfsfunktion, die alle Fälle einheitlich behandelt
const waitFor = async (arr, index, expected, timeout = Infinity) => {
const { async, value } = Atomics.waitAsync(arr, index, expected, timeout);
return async ? value : value; // Promise oder String – await löst beides auf
};
const int32 = new Int32Array(new SharedArrayBuffer(4));
console.log(await waitFor(int32, 0, 0, 50));
// Wichtig · Fallstricke
- Nur mit gemeinsamem Speicher: Das Array muss auf einem
SharedArrayBufferliegen und einInt32ArrayoderBigInt64Arraysein. Sonst wird einTypeErrorausgelöst. - Cross-Origin-Isolation: Im Browser gibt es
SharedArrayBuffernur, wenn die Seite die HeaderCross-Origin-Opener-Policy: same-originundCross-Origin-Embedder-Policy: require-corpsendet. Prüfen lässt sich das mitcrossOriginIsolated. - Immer beide Fälle prüfen:
valueist nicht immer ein Promise. Beiasync: falseist es ein String. Wer direktresult.value.then()aufruft, bekommt dann einen Fehler. - Kein Ereignis ohne notify: Wird der Wert nur geändert, ohne
Atomics.notify()aufzurufen, endet das Warten erst mit dem Timeout. Ohne Timeout bleibt das Promise für immer offen. - Browser-Unterstützung: Chromium und Safari unterstützen die Methode schon länger, Firefox erst seit Kurzem. Vor der Nutzung mit
typeof Atomics.waitAsync === 'function'prüfen und bei Bedarf aufAtomics.wait()in einem Worker ausweichen. - Die Auflösung des Promise läuft über die Event-Loop. Die Reaktion auf
notify()kommt also verzögert und ist nicht für harte Echtzeit-Synchronisation gedacht.