简体   繁体   English

使用带响应的异步 ReadableStream 从 Service Worker 的 fetch 事件中返回 HTML

[英]Use Asynchronous ReadableStream with Response to return HTML from fetch event of Service Worker

This question is similar to my other question but takes into account asynchronous nature inside the ReadableStream .这个问题与我的其他问题类似,但考虑了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.但它似乎没有读取任何enqueue项目。

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.这似乎是有道理的,因为它一次读取所有内容,而不考虑 stream 是否完成。

Resources that I have used:我用过的资源:

https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Examples https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream#Examples

https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/ https://philipwalton.com/articles/smaller-html-payloads-with-service-workers/

Looks like stream likes when you are putting Uint8Array in controller.enqueue method.当您将Uint8Array放入controller.enqueue方法时,看起来像stream喜欢。

With the help of TextEncoder your example works.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; })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM