-
-
Save jakearchibald/d0b7e65496a8ec362f10739c3e28da6e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
async function mergeResponses(responsePromises, headers) { | |
const readers = responsePromises.map(p => Promise.resolve(p).then(r => r.body.getReader())); | |
let doneResolve; | |
let doneReject; | |
const done = new Promise((r, rr) => { | |
doneResolve = r; | |
doneReject = rr; | |
}); | |
const readable = new ReadableStream({ | |
async pull(controller) { | |
const reader = await readers[0]; | |
try { | |
const {done, value} = await reader.read(); | |
if (done) { | |
readers.shift(); | |
if (!readers[0]) { | |
controller.close(); | |
doneResolve(); | |
return; | |
} | |
return this.pull(controller); | |
} | |
controller.enqueue(value); | |
} | |
catch (err) { | |
doneReject(err); | |
throw err; | |
} | |
}, | |
cancel() { | |
doneResolve(); | |
} | |
}); | |
const response = await responsePromises[0]; | |
return { | |
done, | |
response: new Response(readable, { | |
headers: headers || response.headers | |
}) | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This depends on transform streams & async iterators | |
async function mergeResponses(responsePromises, headers) { | |
const {readable, writable} = new TransformStream(); | |
const done = (async function() { | |
for await (const response of responsePromises) { | |
await response.body.pipeTo(writable, {preventClose: true}); | |
} | |
writable.getWriter().close(); | |
})(); | |
return { | |
done, | |
response: new Response(readable, { | |
headers: headers || (await responsePromises[0]).headers | |
}) | |
}; | |
} |
future2.js
const mergeResponses = async (
responsePromises = [Promise.resolve(new Response())],
headers = new Headers()
) => new Response(new ReadableStream({ async start(controller) {
for await (const response of responsePromises) {
// Bonus example: controller.enqueue(await response.text());
await response.body.pipeTo(new WritableStream({
write: (data) => controller.enqueue(data)
}));
}
}}),{
headers: headers.has("Content-Type") ? headers : (await responsePromises[0]).headers
});
// usage example
globalThis.onfetch = (event) => event.respondWith(mergeResponses([...responsePromises]));
The function parameters got set with empty default values for typeInferencing in IDE's
so the above example is 100% Typed
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@PRMSA it allows
responsePromises
to be a mix ofPromise<Response>
and plainResponse
.