如何从ReadableStream对象中获取信息?
我使用的取回API,我没有看到这是清楚的从文档。
主体被返回为一个ReadableStream,我只是想访问这个流中的属性。在浏览器开发工具的Response下,我似乎以JavaScript对象的形式将这些信息组织成属性。
fetch('http://192.168.5.6:2000/api/car', obj)
.then((res) => {
if(!res.ok) {
console.log("Failure:" + res.statusText);
throw new Error('HTTP ' + res.status);
} else {
console.log("Success :" + res.statusText);
return res.body // what gives?
}
})
为了从ReadableStream中访问数据,你需要调用其中一个转换方法(文档可以在这里找到)。
举个例子:
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
// The response is a Response instance.
// You parse the data into a useable format using `.json()`
return response.json();
}).then(function(data) {
// `data` is the parsed version of the JSON returned from the above endpoint.
console.log(data); // { "userId": 1, "id": 1, "title": "...", "body": "..." }
});
编辑:如果你的数据返回类型不是JSON或者你不想要JSON,那么使用text()
举个例子:
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
return response.text();
}).then(function(data) {
console.log(data); // this will be a string
});
你可能问了一个错误的问题来解决你的问题,但这里有一个对你实际问题的答案。灵感可能来自Node.js流/消费者模块的源代码。
body是一个ReadableStream,它以Uint8Arrays的形式发出chunk。下面的函数将收集单个Uint8Array中的所有块:
export async function streamToArrayBuffer(stream: ReadableStream<Uint8Array>): Promise<Uint8Array> {
let result = new Uint8Array(0);
const reader = stream.getReader();
while (true) { // eslint-disable-line no-constant-condition
const { done, value } = await reader.read();
if (done) {
break;
}
const newResult = new Uint8Array(result.length + value.length);
newResult.set(result);
newResult.set(value, result.length);
result = newResult;
}
return result;
}
然后可以使用TextDecoder将数组转换为字符串。然后你可以使用JSON.parse()解析这个字符串:
const buffer = await streamToArrayBuffer(res.body);
const text = new TextDecoder().decode(buffer);
const json = JSON.parse(text);
将来当浏览器支持它时,你也可以使用TextDecoderStream直接收集流内容作为字符串:
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
let result = '';
const reader = stream.pipeThrough(new TextDecoderStream()).getReader();
while (true) { // eslint-disable-line no-constant-condition
const { done, value } = await reader.read();
if (done) {
break;
}
result += value;
}
return result;
}