Vood
Phasis rakendab täielikult WHATWG voogude standardit. Kõik klassid, lugejarežiimid ja abifunktsioonid. Sama kood, mis töötab Node'is ja nüüdisaegsetes brauserites, töötab ka keskkonnas Phasis.
Rakendus on sama, mida fetch ise sisemiselt kasutab — Response.body on päris ReadableStream, Request toetab voogedastusega sisusid ning olemas on ka tee(), mida vajate Response'i kloonimiseks.
Kaasasolev
| Klass | Olek |
|---|---|
ReadableStream |
Täielik |
ReadableStreamDefaultController |
Täielik |
ReadableByteStreamController |
Täielik |
ReadableStreamDefaultReader |
Täielik |
ReadableStreamBYOBReader |
Täielik |
ReadableStreamBYOBRequest |
Täielik |
WritableStream |
Täielik |
WritableStreamDefaultController |
Täielik |
WritableStreamDefaultWriter |
Täielik |
TransformStream |
Täielik |
TransformStreamDefaultController |
Täielik |
ByteLengthQueuingStrategy |
Täielik |
CountQueuingStrategy |
Täielik |
Lisaks on olemas sagedamini kasutatavad meetodid: pipeTo, pipeThrough, tee, getReader, asünkroonne iteratsioon, Symbol.asyncIterator, BYOB-lugemine funktsiooniga { min }.
Andmete väljastamine
// Pull-based — only generates values when read
const counter = new ReadableStream({
start(controller) { this.n = 0; },
pull(controller) {
if (this.n >= 5) { controller.close(); return; }
controller.enqueue(this.n++);
},
});
for await (const v of counter) console.log(v); // 0,1,2,3,4
// Push-based — start enqueues everything eagerly
const small = new ReadableStream({
start(c) {
[10, 20, 30].forEach(n => c.enqueue(n));
c.close();
},
});
Andmete lugemine
Andmete lugemiseks on kolm viisi:
// 1. Reader
const reader = stream.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log(value);
}
reader.releaseLock();
// 2. Async iteration (preferred)
for await (const chunk of stream) {
console.log(chunk);
}
// 3. tee + parallel pipes
const [a, b] = stream.tee();
await Promise.all([a.pipeTo(sinkA), b.pipeTo(sinkB)]);
Teisendamine
const upper = new TransformStream({
transform(chunk, controller) {
controller.enqueue(chunk.toUpperCase());
},
});
const result = new ReadableStream({
start(c) { ['hi', 'there'].forEach(s => c.enqueue(s)); c.close(); }
}).pipeThrough(upper);
for await (const v of result) console.log(v); // HI, THERE
Baidivood (BYOB)
const bytes = new ReadableStream({
type: 'bytes',
start(controller) {
controller.enqueue(new Uint8Array([1, 2, 3, 4, 5, 6]));
controller.close();
},
});
const reader = bytes.getReader({ mode: 'byob' });
const buf = new Uint8Array(4);
const { value, done } = await reader.read(buf);
// value is a Uint8Array of length 4, sharing buffer with `buf`
{ min: N } on toetatud — read(view, { min: 2 }) lahendatakse alles siis, kui saadaval on vähemalt 2 elementi.
Tagasisurve
desiredSize ja ready töötavad nii, nagu spetsifikatsioon ette näeb. Kasutage järjekorda seadmisstrateegiat, et anda tootjale tagasisidet:
const stream = new ReadableStream({
pull(controller) {
if (controller.desiredSize <= 0) return; // back off
controller.enqueue(nextChunk());
},
}, new CountQueuingStrategy({ highWaterMark: 4 }));
Fetchiga
// Response body is a ReadableStream
const res = await fetch('https://example.com/big.txt');
let total = 0;
for await (const chunk of res.body) {
total += chunk.byteLength;
}
// Request bodies can stream too
const upload = new ReadableStream({
start(c) { c.enqueue(new TextEncoder().encode('hello')); c.close(); }
});
await fetch('https://example.com/upload', { method: 'POST', body: upload });
Kaheks jagamine vahemällu salvestamiseks
Levinud muster: loe sisu kaks korda.
const res = await fetch(url);
const [forCache, forUse] = res.body.tee();
await Promise.all([
forCache.pipeTo(cacheWritable),
parseJson(forUse),
]);
Response.clone() teeb seda teie eest ja tagastab uue Response.
Piirangud
- Ainult sünkroonsed andmetootjad.
pull(), mis teeb blokeerivat PHP I/O-d, peatab skripti töö. Kasutage HTTP jaoks fetchi transpordikonksu; failide puhul eelistage need esmalt mällu lugeda. Saadaval onsetTimeout/setInterval(vt Sündmuste tsükkel), kuid mootor kasutab vaikimisi virtuaalaega —pull()sees olevsetTimeout(cb, 1000)ei maga PHP, vaid nihutab tsükli kella edasi. Reaalajas ajastamiseks peab host käitamatickEventLoop()seinakella järgi.
Vt ka
- Veebiliidesed (WPT) — voogude alamtestide WPT läbimise määra tabel.
- Fetchi transport — kuidas päringute ja vastuste sisu liigub üle PHP/JS piiri.
- AbortControlleri kasutusmustrid — käimasolevate lugemiste tühistamine.