Fetch API 是现代 Web 开发中的一个重要组成部分,它提供了一种简单且一致的方式来访问网络资源。Fetch API 的一个强大功能就是能够处理流式响应,即服务器可以分块发送数据,而不是一次性发送整个文件,这样浏览器就可以立即开始显示接收到的数据,而不需要等待整个文件下载完毕。
要实现 fetch 的流式输出,关键在于如何正确地处理返回的 ReadableStream 对象。ReadableStream 是 HTML 标准的一部分,它代表了一个可以从内部读取数据的源头。在 Fetch API 中,Response 对象的 body 属性就是一个 ReadableStream 实例。
为了实现流式输出,可以使用 TransformStream 类来处理数据流。TransformStream 可以对数据流进行转换,例如在这里,我们可以将 Response 对象的 ReadableStream 转换为字符串流,然后逐个处理每个字符,模拟 ChatGPT 的打字机效果。
下面是一个简单的示例,展示了如何使用 fetch API 和 TransformStream 来实现类似于 ChatGPT 的流式输出:
fetch('https://example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.body;
})
.then(stream => {
const reader = stream.getReader();
const transformer = new TransformStream();
const writer = transformer.writable.getWriter();
function readChunk() {
reader.read().then(({ value, done }) => {
if (done) {
// 数据流结束
console.log('Done reading the stream');
return;
}
writer.write(value); // 写入转换后的数据
setTimeout(readChunk, 1000); // 延时1秒后继续读取下一个数据块
});
}
readChunk(); // 启动读取流程
})
.catch(error => {
console.error('Error:', error);
});
在这个例子中,fetch 函数发起一个 HTTP 请求,然后返回的 Response 对象的 body 是一个 ReadableStream 实例。我们通过 getReader 方法获取到这个流的读取器,然后创建一个新的 TransformStream 实例来处理数据流。TransformStream 的 writable 属性也是一个 ReadableStream 实例,我们可以通过 getWriter 方法获取写入器,然后将接收到的数据块写入到这个写入器中。
注意,这里使用了 setTimeout 函数来模拟打字机的打字速度,你可以根据实际需求调整这个时间间隔。
以上就是 fetch 实现流式输出的基本原理和方法。通过这种方式,可以实现类似于 ChatGPT 的动态、逐步展示数据的效果,提高用户体验。