Using fetch
const response = await fetch("/endpoint", {
signal: AbortSignal.timeout(10000),
});
const reader = response.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) {
console.log("Stream complete");
break;
}
console.log(new TextDecoder().decode(value));
}
XHR
var xhr = new XMLHttpRequest();
xhr.open('GET', '/endpoint', true);
xhr.timeout = 10000;
xhr.ontimeout = function() {
console.error('Request timed out!');
};
xhr.onprogress = function() {
var responseText = xhr.responseText;
var chunk = responseText.slice(xhr.prevLen);
xhr.prevLen = responseText.length;
console.log(chunk);
};
xhr.onload = function() {
console.log('Done!');
};
xhr.send();
Axios:
Not supported. Said to be impossible in 2009, closed in 2016, and there's still no support for it today.
General API:
async function GET(req, res) {
res.write('hello')
await new Promise((resolve) => setTimeout(resolve, 1000))
res.write('world')
res.end()
}
Optional: Next.js 14 endpoint:
import { NextApiResponse } from 'next'
// https://developer.mozilla.org/docs/Web/API/ReadableStream#convert_async_iterator_to_stream
function iteratorToStream(iterator: any) {
return new ReadableStream({
async pull(controller) {
const { value, done } = await iterator.next()
if (done) {
controller.close()
} else {
controller.enqueue(value)
}
},
})
}
function sleep(time: number) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
const encoder = new TextEncoder()
async function* makeIterator() {
yield encoder.encode('<p>One</p>')
await sleep(700)
yield encoder.encode('<p>Two</p>')
await sleep(700)
yield encoder.encode('<p>Three</p>')
}
export default async function handler(req, res: NextApiResponse<any>) {
const iterator = makeIterator()
const stream = iteratorToStream(iterator)
return new Response(stream)
}
export const runtime = 'edge'