Streaming 助手
Streaming 助手提供了一组用于返回流式响应的方法。
导入
ts
import { Hono } from 'hono'
import { stream, streamText, streamSSE } from 'hono/streaming'stream()
返回一个基础的流式响应(Response 对象)。
ts
app.get('/stream', (c) => {
return stream(c, async (stream) => {
// 在终止时执行的处理。
stream.onAbort(() => {
console.log('Aborted!')
})
// 写入 Uint8Array。
await stream.write(new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]))
// 管道转发可读流。
await stream.pipe(anotherReadableStream)
})
})streamText()
返回带有 Content-Type:text/plain、Transfer-Encoding:chunked 以及 X-Content-Type-Options:nosniff 头部的流式响应。
ts
app.get('/streamText', (c) => {
return streamText(c, async (stream) => {
// 写入携带换行符('\n')的文本。
await stream.writeln('Hello')
// 等待 1 秒。
await stream.sleep(1000)
// 写入不带换行的文本。
await stream.write(`Hono!`)
})
})WARNING
在 Cloudflare Workers 中开发时,流式传输可能无法在 Wrangler 中正常工作。此时可以将 Content-Encoding 头设置为 Identity。
ts
app.get('/streamText', (c) => {
c.header('Content-Encoding', 'Identity')
return streamText(c, async (stream) => {
// ...
})
})streamSSE()
用于无缝推送 Server-Sent Events(SSE)。
ts
const app = new Hono()
let id = 0
app.get('/sse', async (c) => {
return streamSSE(c, async (stream) => {
while (true) {
const message = `It is ${new Date().toISOString()}`
await stream.writeSSE({
data: message,
event: 'time-update',
id: String(id++),
})
await stream.sleep(1000)
}
})
})错误处理
Streaming 助手的第三个参数是错误处理函数。该参数可选,如果未提供,错误会被输出到控制台。
ts
app.get('/stream', (c) => {
return stream(
c,
async (stream) => {
// 在终止时执行的处理。
stream.onAbort(() => {
console.log('Aborted!')
})
// 写入 Uint8Array。
await stream.write(
new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f])
)
// 管道转发可读流。
await stream.pipe(anotherReadableStream)
},
(err, stream) => {
stream.writeln('An error occurred!')
console.error(err)
}
)
})回调执行完毕后,流会自动关闭。
WARNING
如果 Streaming 助手的回调函数抛出错误,将不会触发 Hono 的 onError 事件。
onError 用于在响应发送前拦截错误并覆盖响应。然而在回调执行时,流已经开始传输,因而无法再覆盖。