fetch ReadableStream
递归
details
fetch('xxxx')
.then(res => res.body)
.then(stream => {
const reader = stream.getReader();
console.log('reader', reader);
// reader.read().then(res => {
// console.log(res);
// });
let count = 0;
const recursiveRead = () => {
reader.read().then(res => {
count += 1;
console.log(res);
if (!res.done) {
return recursiveRead();
}
console.log('count', count);
});
};
return recursiveRead();
});
Async Iterator
details
fetch('xxxx')
.then(res => res.body)
.then(async stream => {
const reader = stream.getReader();
let asyncIterator = {
[Symbol.asyncIterator]() {
return {
next() {
return reader.read();
},
};
},
};
for await (const chunk of asyncIterator) {
console.log(chunk);
}
});
Generator
details
fetch('xxx')
.then(res => res.body)
.then(async stream => {
async function* chunkGenerator(stream) {
const reader = stream.getReader();
try {
while (true) {
const { value, done } = await reader.read();
if (done) {
break;
}
yield value;
}
} catch (err) {
console.log('err', err);
} finally {
reader.releaseLock();
}
}
for await (const chunk of chunkGenerator(stream)) {
console.log(chunk);
}
});
TextDecoder 解码
details
import { TextDecoder } from 'util';
fetch('xxx')
.then(res => res.body)
.then(async stream => {
const decoder = new TextDecoder();
// async function* chunkGenerator(stream) {
// const reader = stream.getReader();
// try {
// while (true) {
// const { value, done } = await reader.read();
// if (done) {
// break;
// }
// yield value;
// }
// } catch (err) {
// console.log('err', err);
// } finally {
// reader.releaseLock();
// }
// }
for await (const chunk of chunkGenerator(stream)) {
console.log(chunk, decoder.decode(chunk, { stream: true }));
}
});
pipe stream
details
fetch('https://www.example.org')
.then((response) => response.body)
.then((rb) => {
const reader = rb.getReader();
return new ReadableStream({
start(controller) {
// The following function handles each data chunk
function push() {
// "done" is a Boolean and value a "Uint8Array"
reader.read().then(({ done, value }) => {
// If there is no more data to read
if (done) {
console.log('done', done);
controller.close();
return;
}
// Get the data and send it to the browser via the controller
controller.enqueue(value);
// Check chunks by logging to the console
console.log(done, value);
push();
});
}
push();
},
});
})
.then((stream) =>
// Respond with our stream
new Response(stream, { headers: { 'Content-Type': 'text/html' } }).text()
)
.then((result) => {
// Do things with result
console.log(result);
});
Refer