javascript - 使用 fetch API 进行流式传输
问题描述
我创建了 .NET Core API,并在其中公开了一个 POST 端点,该端点将响应流式传输到多个块上,其中每个块包含一个 JSON 对象,并且我创建了 Angular 客户端应用程序,该应用程序通过 fetch API 查询该端点:
const response = await fetch(environment.apiUrl + `/Vehicle/ParseVehiclesData`,
{
method: 'post',
body: file,
});
const reader = response.body.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
let res = JSON.parse(new TextDecoder("utf-8").decode(value));
console.log(res);
}
我的目标是提供一个进度条,其中包含有关他们已经在每个块中从服务器返回的进度的信息,现在我遇到的问题是当连接速度较弱的用户尝试它时会发生一种行为,他们的消费速度每个块的速度小于服务器提要的速度,这会导致浏览器在存在背压时将块合并在一起,因此我解析解码字符串的尝试失败,因为我将尝试解析类似
{"name":"abc","progress":50}{"name":"ab1","progress":100"}
多个 json 对象将附加在一起,没有分隔符,甚至没有断行,所以我正在寻找的是一种解决方案,它可以防止在有背压时合并块,或者在最坏的情况下解析 JSON 对象的方法没有分隔符并将它们提供给自定义流或可观察对象,我们将不胜感激有关该主题的任何帮助。
这些是我在搜索时偶然发现的一些文章, InternetSpeed
解决方案
您可以定义一个预解析器来按}{
分隔符拆分消息(并处理第一个/最后一个条目):
let preParser = (a)=>a.split('}{').map((item,index) => {
if(a.split('}{').length>1){
if (index== 0){return item+'}'} // first msg
else if (index<a.split('}{').length-1){return '{'+item+'}'} // middle msgs
else {return '{'+item}} // last msg
else {return a} // no need to do anything if single msg
})
a='{"name":"abc","progress":50}'
b='{"name":"abc","progress":50}{"name":"ab1","progress":100}{"name":"ab2","progress":150}'
console.log('example 1')
preParser(a).forEach(v => console.log(JSON.parse(v)))
console.log('example 2')
preParser(b).forEach(v => console.log(JSON.parse(v)))
推荐阅读
- xamarin - 当应用程序进入后台或绘制通知面板时,Xamarin iOS api 调用突然失败
- flutter - 如何使 HTML() 小部件中的 html 可选
- python - 在/没有这样的表处出现操作错误:即使在创建表后也有 tasks_task
- node.js - useEffect 挂钩中的函数未运行
- python - python提取数据列并将它们并排放置
- spring - atomikos (JTA) 在哪里保持状态?
- javascript - 如何在 Vue.js 中的方法内触发输入焦点事件?
- javascript - How to add dotted lines between two interval of x-axis in hightcharts
- mysql - 在 mariadb 存储过程查询中需要快速的小帮助-
- c# - 由于外部库导致的部署问题