I'm trying to convert a chain of promises .then().catch to async/await functions
const chain = [
{
onFulfilled: () => {/*some logic*/},
onRejected: () => {/*some logic*/},
{
onFulfilled: () => {/*some logic*/},
onRejected: () => {/*some logic*/},
{
onFulfilled: () => {/*some logic*/},
onRejected: () => {/*some logic*/},
},
//...
];
const data = 'initial data';
let promise = Promise.resolve(data);
let i = 0;
while (i < chain.length) {
promise = promise.then(chain[i].onFulfilled).catch(chain[i].onRejected);
i++;
}
The final promise is equal to:
promise = Promise.resolve()
.then(chain[0].onFulfilled).catch(chain[0].onRejected)
.then(chain[1].onFulfilled).catch(chain[1].onRejected)
.then(chain[2].onFulfilled).catch(chain[2].onRejected)
....
Here is what I've tried so far
let data = 'initial data';
for (const fn of chain) {
try {
data = await fn.onFulfilled(data);
} catch (e) {
data = await fn.onRejected(e);
}
}
The prolem is: if fn.onRejected throw an error, the error causes for loop to stop rather than handled by the next fn.onRejected
Here is the working code. Messy but works
let data = 'initial data', unhandledError;
for (const fn of chain) {
if(unhandledError) {
try {
data = await fn.onRejected(unhandledError);
unhandledError = null;
} catch (e) {
unhandledError = e;
}
continue;
}
try {
data = await fn.onFulfilled(data);
unhandledError = null;
} catch (e) {
try {
data = await fn.onRejected(e);
unhandledError = null;
} catch (e) {
unhandledError = e;
}
}
if(unhandledError) throw unhandledError;