Es ist einfacher, mit vielversprechenden "Schöpfern" (= Funktion, die Versprechen zurückgibt) zu arbeiten, als mit rohen Versprechen. Definieren Sie zunächst:
const fetchJson = (url, opts) => () => fetch(url, opts).then(r => r.json())
was einen solchen "Schöpfer" zurückgibt. Hier sind zwei Dienstprogramme für die serielle und parallele Verkettung, die sowohl rohe Versprechen als auch "Schöpfer" akzeptieren:
const call = f => typeof f === 'function' ? f() : f;
const parallel = (...fns) => Promise.all(fns.map(call));
async function series(...fns) {
let res = [];
for (let f of fns)
res.push(await call(f));
return res;
}
Dann kann der Hauptcode folgendermaßen geschrieben werden:
let [[getTokenData, writeToDBData], frontEndData] = await parallel(
series(
fetchJson(url_for_getToken),
fetchJson(url_for_writeToDB),
),
fetchJson(url_for_frontEnd),
)
Wenn Ihnen der dedizierte "Creator" -Wrapper nicht gefällt, können Sie ihn fetchJson
normal definieren
const fetchJson = (url, opts) => fetch(url, opts).then(r => r.json())
und verwenden Sie Inline-Fortsetzungen genau dort, wo series
oder parallel
aufgerufen werden:
let [[getTokenData, writeToDBData], frontEndData] = await parallel(
series(
() => fetchJson('getToken'),
() => fetchJson('writeToDB'),
),
() => fetchJson('frontEnd'), // continuation not necessary, but looks nicer
)
Um die Idee weiter voranzutreiben, können wir auch "Schöpfer" machen series
und parallel
zurückgeben, anstatt Versprechen. Auf diese Weise können wir beliebig verschachtelte "Schaltkreise" aus seriellen und parallelen Versprechungen erstellen und die Ergebnisse in der richtigen Reihenfolge erhalten. Vollständiges Arbeitsbeispiel:
const call = f => typeof f === 'function' ? f() : f;
const parallel = (...fns) => () => Promise.all(fns.map(call));
const series = (...fns) => async () => {
let res = [];
for (let f of fns)
res.push(await call(f));
return res;
};
//
const request = (x, time) => () => new Promise(resolve => {
console.log('start', x);
setTimeout(() => {
console.log('end', x)
resolve(x)
}, time)
});
async function main() {
let chain = series(
parallel(
series(
request('A1', 500),
request('A2', 200),
),
series(
request('B1', 900),
request('B2', 400),
request('B3', 400),
),
),
parallel(
request('C1', 800),
series(
request('C2', 100),
request('C3', 100),
)
),
);
let results = await chain();
console.log(JSON.stringify(results))
}
main()
.as-console-wrapper { max-height: 100% !important; top: 0; }