Signatur
Beschreibung
Die Eigenschaft locked liefert true, sobald ein Leser über getReader() für den Stream angelegt wurde oder der Stream gerade per pipeTo() bzw. pipeThrough() weitergeleitet wird. Ein gesperrter Stream kann nur noch über diesen einen Leser gelesen werden. Weitere Aufrufe von getReader(), tee(), cancel() oder pipeTo() schlagen dann fehl.
Die Sperre sorgt dafür, dass immer nur ein Konsument die Daten eines Streams liest. Sonst könnten zwei Stellen im Code Teile (Chunks) „stehlen“ und die Daten würden unvollständig ankommen. Erst mit reader.releaseLock() wird der Stream wieder freigegeben, und locked ist danach wieder false.
In der Praxis nutzt man locked vor allem als Schutzprüfung: bevor man einen Stream an eine Hilfsfunktion übergibt, getReader() aufruft oder einen Response-Body weiterverarbeitet. Bei fetch gilt: response.body.locked ist true, sobald der Body gelesen wird, zum Beispiel über response.json().
Rückgabewert
true, wenn der Stream an einen Leser gebunden ist oder gerade weitergeleitet wird (Pipe), sonst false.Beispiele
Sperrzustand vor und nach getReader()
const stream = new ReadableStream({
start(controller) {
controller.enqueue('Hallo');
controller.close();
}
});
console.log(stream.locked); // false
const reader = stream.getReader();
console.log(stream.locked); // true
reader.releaseLock();
console.log(stream.locked); // false
Sicheres Lesen mit Schutzprüfung
const readAllText = async (stream) => {
if (stream.locked) {
throw new Error('Stream wird bereits von einem anderen Leser verwendet');
}
const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
let text = '';
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
text += value;
}
} finally {
reader.releaseLock();
}
return text;
};
const stream = new Blob(['Streams sind praktisch']).stream();
console.log(await readAllText(stream));
Response-Body nach dem Lesen gesperrt
const response = new Response('{"ok":true}');
console.log(response.body.locked); // false
const data = await response.json();
console.log(response.body.locked); // true
console.log(response.bodyUsed); // true
console.log(data);
Sperre während pipeTo()
const source = new ReadableStream({
start(c) { c.enqueue('a'); c.close(); }
});
const sink = new WritableStream({ write(chunk) { console.log('geschrieben:', chunk); } });
const piping = source.pipeTo(sink);
console.log(source.locked); // true
await piping;
console.log(source.locked); // false
// Wichtig · Fallstricke
- Nur lesbar: Wenn du
lockedeinen Wert zuweist, passiert nichts. Im Strict Mode wird einTypeErrorgeworfen, weil die Eigenschaft nur einen Getter hat. - Gesperrt heißt nicht beendet:
lockedsagt nichts darüber, ob der Stream geschlossen oder fehlerhaft ist. Auch ein vollständig gelesener Stream bleibt gesperrt, bisreleaseLock()aufgerufen wird. Ob ein Stream geschlossen ist, erkennst du anreader.closedoder andonebeiread(). - Gesperrte Streams:
getReader(),tee(),pipeTo()undpipeThrough()werfen bei einem gesperrten Stream einenTypeError.stream.cancel()gibt in diesem Fall ein abgelehntes Promise zurück. OhnereleaseLock()in einemfinally-Block bleibt der Stream für immer gesperrt. - releaseLock() mit offenen Leseaufrufen: Laut aktueller Spezifikation werden offene
read()-Promises dabei mit einemTypeErrorabgelehnt. Ältere Browserversionen haben stattdessen selbst einen Fehler geworfen. - Kompatibilität: Wird in allen modernen Browsern unterstützt. In Node.js steht die Eigenschaft über
stream/webab 16.5 zur Verfügung und ist ab 18 global verfügbar.