问题
This question is similar to my other question but takes into account asynchronous nature inside the ReadableStream
.
This is my test code now:
const stream = new ReadableStream({
start(c) {
let i = 1
const t = setInterval(test, 5e2)
function test() {
c.enqueue("<h1>Yellow!</h1>")
if (i++ === 5) {
clearInterval(t)
c.close()
}
}
}
})
event.respondWith(new Response(stream, {headers: {"content-type": "text/html"}}))
The above code is not rendered by the browser and I'm not sure why. According to examples online it seems like it should work. But it doesn't appear to be reading any of the enqueue
items.
Note in my other question the answer at least rendered the first response:
const createStream = () => new ReadableStream({
start(controller) {
controller.enqueue("<h1 style=\"background: yellow;\">Yellow!</h1>")
controller.close()
}
})
const secondStream = createStream().getReader();
secondStream.read()
.then(({
value
}) => {
return new Response(value, {
headers: {
"Content-Type": "text/html"
}
});
})
.then(response => response.text())
.then(text => {
console.log(text);
});
Which seems to make sense as it is reading everything at once without regard to if the stream is finished.
Resources that I have used:
https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Examples
https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/
回答1:
Looks like stream
likes when you are putting Uint8Array
in controller.enqueue
method.
With the help of TextEncoder your example works.
const data = [
{name: "Yellow", value: 'yellow'},
{name: "Green", value: 'green'},
{name: "Blue", value: 'blue'},
{name: "Red", value: 'red'},
{name: "Orange", value: 'orange'},
]
const encoder = new TextEncoder();
const stream = new ReadableStream({
start(controller) {
let i = 1
const handle = setInterval(test, 5e2)
function test() {
const {name, value} = data[i - 1];
controller.enqueue(encoder.encode(`<h1 style="color: ${value};">${name}!</h1>`))
if (i++ === 5) {
clearInterval(handle)
controller.close()
}
}
}
})
new Response(stream, {headers: {"content-type": "text/html"}})
.text().then(text => {
document.body.innerHTML = text;
})
来源:https://stackoverflow.com/questions/62461511/use-asynchronous-readablestream-with-response-to-return-html-from-fetch-event-of