当前位置: 首页 > 知识库问答 >
问题:

javascript - 前端使用fetch请求streams api,使用read()处理返回的response时,为什么第一次会出现阻塞?

郑琦
2024-06-26

使用fetch请求streams api的,当请求开始响应的时候,使用read()将返回的流式数据转成可展示的数据,然后通过while循环重复以上过程达到流式展示的效果;
问题:
第一次使用read()解析返回数据的时候,会执行很长时间,阻塞了后续执行;之后会将请求每次返回的数据一次性处理执行;造成的实际页面效果是:页面会空白很长时间,然后突然把所有的数据展示出来了,失去了流式的效果;

        const response = await fetch(url, {          method: 'POST',          headers: {            [Authorization]: getAuthorization(),            'Content-Type': 'application/json',          },          body: JSON.stringify(body),        });        const reader = response.body          ?.pipeThrough(new TextDecoderStream())          .pipeThrough(new EventSourceParserStream())          .getReader();        while (true) {          // 第一次console时间          console.log(new Date().getTime());          const x = await reader?.read();          // 第二次console时间          console.log(new Date().getTime());          if (x) {            const { done, value } = x;            console.log('value', value)            try {              // 处理展示streams数据             } catch (e) {              console.warn(e);            }            if (done) {              console.info('done');              break;            }          }        }

第一次和第二次时间打印之间间隔了几十s,是因为await reader?.read();语句导致的,但不知道什么原因导致的;
之后循环的每一次过程2此时间打印间隔都很小且都为流式数据正确的结果,从循环第二次开始到循环结束大概只有几十ms的时间;
造成的影响就是页面空白了几十s,然后所有的数据就突然展示出来,并不是每个字轮流出现的效果;

有没有大佬能帮忙,是因为第一次的read()执行将之后所有的返回数据都处理了并等待streams api达到done状态后才执行后面的内容造成了阻塞效果,还是因为其它原因。

同一个服务接口用在其它页面上是能展示正确的流式输出效果的;

共有1个答案

晏正豪
2024-06-26

看不出有什么问题,会不会是你的接口并不是流式返回数据,而是攒够了一次性返回?如果使用 nginx,默认就是如此。

 类似资料:
  • 最近项目中一直会出现一个比较奇怪的现象:偶尔有用户会重复触发某个接口,但是埋点记录能确定在前端的代码里只发起了一次,前端也没重试的机制。从用户的UA以及环境找不到共同点,在网上搜了下说有可能是nginx的重试机制 https://www.cnblogs.com/caibaotimes/p/15407971.html 我们的项目都是走公司统一的结构、构建以及发布(react)所以我想问下 1、怎么确

  • 我想在RxJava中实现一个下载一些文件的处理队列。我想下载的文件数量可能高达100个左右。 一切都是在Android上使用RxJava 1.1.1开发的 我做错了什么?

  • 前端返回的json如下: 请问pojo类(如下图)里面相应变量类型应当如何定义?

  • 问题内容: 我们有一个node.js服务器,该服务器将REST API实施为中央服务器的代理,而中央服务器具有一个略有不同且不对称的REST API。 我们的客户端运行在各种浏览器中,它要求节点服务器从中央服务器获取任务。节点服务器从中央服务器获取所有任务ID的列表,并将其返回给客户端。然后,客户端通过代理对每个ID进行两次REST API调用。 据我所知,这些工作都是异步完成的。在控制台日志中,

  • 问题内容: 我很少使用SQL,也无法在档案库中找到任何类似的内容,所以我问一个简单的查询问题:我需要一个查询,该查询返回 personID 且仅返回第一个 seeedTime 记录: 想要的结果: 那就是我做过的和失败的: PS:注意SQL CE 4 问题答案: 如果您的seenTime增加,随着seenID增加: 更新另一种情况: 如果不是这种情况,并且您确实希望SeenedTime与最小的se

  • 当我在输入元素中输入第一个字符时,我得到“空字符串”。 在我看来,我在输入元素中输入一个字符,触发“onChange”事件,运行函数getTitle,设置“title”变量,该变量连接到useState钩子,然后控制结果。按照这个推理,我希望输入第一个字符。相反,我得到的是“空字符串”。从第二个字符开始,控制台打印字符。 对于“onInput”,函数也会发生同样的情况。 如何解决这个问题,为什么会