我试图在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);
});
});
Stream api 参考是:-
但是react-native的fetch实现似乎与浏览器的差别不大,并且像在web上使用Stream一样不容易使用。
react-native 上已经存在一个未解决的问题 https://github.com/facebook/react-native/issues/12912
在网络上,我们可以从 response.body.getReader() 访问 Stream,其中响应只是从流 url 的 fetch 调用返回的正常结果,但在 React-native 中,我们无法访问 body,因此可以从响应中访问 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);
});
我的两种方法可能都做错了,所以将来几乎没有什么指导可以帮助我或其他人。或者我可能需要找到一种通过编写桥梁来本地完成此操作的方法。
如果您使用的是 React Native,以前不可能做到这一点。
但是现在可以通过 https://github.com/react-native-community/fetch进行流式传输。
这实际上是一个 bug,RN 团队有一段时间从未解决过,这个存储库的出现是为了提供符合 WHATWG 规范的更好的获取
这是 GitHub 的 fetch polyfill 的一个分支,React Native 目前提供了 fetch 实现。该项目采用直接构建在 React Native 网络 API 之上的替代 fetch 实现,而不是 XMLHttpRequest 来提高性能。同时,它旨在填补 WHATWG fetch 规范的一些空白,即对文本流的支持。
使用方法如下:
这个简洁的步骤来自数小时的调试,我不想浪费您的时间。
$ npm install react-native-fetch-api --save
现在安装polyfills:
$ npm install react-native-polyfill-globals
将 polyfill 与 fetch 结合使用:
将以下代码添加到应用程序入口文件index.js(位于项目根目录)的顶部。现在您的新 Fetch 可在全球范围内使用。
import { polyfill as polyfillFetch } from 'react-native-polyfill-globals/src/fetch';
polyfill();
现在您可以像普通浏览器获取一样使用流对象。确保指定选项
textStreaming
true。
fetch('https://jsonplaceholder.typicode.com/todos/1', { reactNative: { textStreaming: true } })
.then(response => response.body)
.then(stream => ...)
希望这有帮助!