Liigu sisu juurde

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

JavaScript
// 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
JavaScript
// 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:

JavaScript
// 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

JavaScript
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)

JavaScript
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:

JavaScript
const stream = new ReadableStream({
  pull(controller) {
    if (controller.desiredSize <= 0) return;  // back off
    controller.enqueue(nextChunk());
  },
}, new CountQueuingStrategy({ highWaterMark: 4 }));

Fetchiga

JavaScript
// 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.

JavaScript
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 on setTimeout / setInterval (vt Sündmuste tsükkel), kuid mootor kasutab vaikimisi virtuaalaega — pull() sees olev setTimeout(cb, 1000) ei maga PHP, vaid nihutab tsükli kella edasi. Reaalajas ajastamiseks peab host käitama tickEventLoop() seinakella järgi.

Vt ka