在 React-Native 应用程序中使用 fetch 流式传输 api

Man*_*ngh 5 stream react-native react-native-fetch-blob

我试图在react-native应用程序中使用带有fetch的Stream api,我在jeakearchibald.com提到的一个很好的例子的帮助下实现了。代码类似于:-

fetch('https://html.spec.whatwg.org/').then(function(response) {
  console.log('response::-', response)
  var reader = response.body.getReader();
  var bytesReceived = 0;

  reader.read().then(function processResult(result) {
    if (result.done) {
      console.log("Fetch complete");
      return;
    }
    bytesReceived += result.value.length;
    console.log(`Received ${bytesReceived} bytes of data so far`);

    return reader.read().then(processResult);
  });
});
Run Code Online (Sandbox Code Playgroud)

流 API 参考是:-

https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

但看起来react-native的fetch实现与浏览器的差别不大,并且像在web上使用Stream一样使用Stream并不容易。

对于相同的https://github.com/facebook/react-native/issues/12912,react-native上已经存在未解决的问题

在网络上,我们可以从response.body.getReader()访问Stream ,其中response只是从流url的fetch调用返回的正常结果,但在react-native中,我们无法访问body,因此可以从fetch调用的响应访问getReader 。

因此,为了克服这个问题,我尝试使用rn-fetch-blob npm package,因为它支持流,但这似乎仅支持来自区域设置文件路径,因为 readStream 函数似乎不支持传递授权和其他必要的标头,所以我尝试将 RNFetchBlob.fetch 与远程 url 和必要的标头一起使用,然后使用响应中的 readStream 方法,但总是返回当前响应没有流。

RNFetchBlob.fetch('GET', 'https://html.spec.whatwg.org/')
      .progress((received, total) => {
        console.log('progress', received / total);
      })
      .then((resp) => {
        // const path = resp.path();
        console.log('resp success:-', resp);
        RNFetchBlob.fs.readStream(path, 'utf8').then((stream) => {
          let data = '';
          stream.open();
          stream.onData((chunk) => {
            data += chunk;
          });
          stream.onEnd(() => {
            console.log('readStream::-', data);
          });
        // });
      })
      .catch((err) => {
        console.log('trackAppointmentStatus::-', err);
      });
Run Code Online (Sandbox Code Playgroud)

我的两种方法可能都做错了,所以将来很少有指导可以帮助我或其他人。或者我可能需要找到一种通过编写桥梁来本地完成此操作的方法。

Cod*_* YT 7

如果你使用的是React Native,以前是不可能做到这一点的。

但现在可以通过https://github.com/react-native-community/fetch进行流式传输。

这实际上是 RN 团队一段时间以来从未解决过的一个错误,这个存储库的出现是为了提供符合 WHATWG 规范的更好的获取

这是 GitHub 的 fetch polyfill 的一个分支,React Native 目前提供了 fetch 实现。该项目采用直接构建在 React Native 网络 API 之上的替代 fetch 实现,而不是 XMLHttpRequest 来提高性能。同时,它旨在填补 WHATWG fetch 规范的一些空白,即对文本流的支持。

使用方法如下:

安装

这些简洁的步骤来自数小时的调试,我不想浪费您的时间。

$ npm install react-native-fetch-api --save
Run Code Online (Sandbox Code Playgroud)

现在安装polyfills:

$ npm install react-native-polyfill-globals
Run Code Online (Sandbox Code Playgroud)

将 polyfill 与 fetch 一起使用:

将以下代码添加到应用程序入口文件 index.js(位于项目根目录)的顶部。现在,您的新 Fetch 已在全球推出。

import { polyfill as polyfillFetch } from 'react-native-polyfill-globals/src/fetch';
polyfill();
Run Code Online (Sandbox Code Playgroud)

现在您可以像普通浏览器获取一样使用流对象。确保指定选项textStreamingtrue。

fetch('https://jsonplaceholder.typicode.com/todos/1', { reactNative: { textStreaming: true } })
  .then(response => response.body)
  .then(stream => ...)
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!