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

作者站长头像
站长
· 阅读数 11

使用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个回答
avatar
test
2024-07-05
回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容