使用 Asynchronous ReadableStream with Response 从 Service Worker 的 fetch 事件返回 HTML [英] Use Asynchronous ReadableStream with Response to return HTML from fetch event of Service Worker
问题描述
这个问题类似于我的另一个问题,但考虑到 ReadableStream
内部的异步性质.
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"}}))
上面的代码不是由浏览器呈现的,我不知道为什么.根据在线示例它似乎应该可以工作.但它似乎没有读取任何 enqueue
项.
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.
我使用过的资源:
https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Examples
https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/
推荐答案
当你将 Uint8Array
放入 controller.enqueue
时,看起来像 stream
> 方法.
Looks like stream
likes when you are putting Uint8Array
in controller.enqueue
method.
借助 TextEncoder
你的例子有效.
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;
})
这篇关于使用 Asynchronous ReadableStream with Response 从 Service Worker 的 fetch 事件返回 HTML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!