将异步 ReadableStream 与对 return HTML 的响应从 Service Worker 的获取事件中使用
Use Asynchronous ReadableStream with Response to return HTML from fetch event of Service Worker
这个问题类似于 但考虑到了 ReadableStream
内部的异步性质。
这是我现在的测试代码:
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"}}))
上面的代码不是由浏览器呈现的,我不确定为什么。 According to examples online 看起来应该可以。但它似乎没有阅读任何 enqueue
项。
注意在我的另一个问题中答案至少呈现了第一反应:
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);
});
这似乎是有道理的,因为它会立即读取所有内容,而不考虑流是否已完成。
我用过的资源:
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
喜欢。
在 TextEncoder
的帮助下,您的示例有效。
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;
})
这个问题类似于 ReadableStream
内部的异步性质。
这是我现在的测试代码:
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"}}))
上面的代码不是由浏览器呈现的,我不确定为什么。 According to examples online 看起来应该可以。但它似乎没有阅读任何 enqueue
项。
注意在我的另一个问题中答案至少呈现了第一反应:
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);
});
这似乎是有道理的,因为它会立即读取所有内容,而不考虑流是否已完成。
我用过的资源:
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
喜欢。
在 TextEncoder
的帮助下,您的示例有效。
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;
})