JSFiddle - React, Tailwind, and code Playground
JavaScript
function CustomPromiseChain(events) {
// Extract the main event and store it in its own variable
const mainEvent = events.main;
delete events.main;
let eventHandlers = {};
// Add functions to register the event handlers
for (let eventName of Object.keys(events)) {
this[eventName] = function (callback) {
eventHandlers[eventName] = callback;
return this;
};
}
// Add the catch event handler
eventHandlers.catch = function (err) {
throw err;
};
this.catch = function (callback) {
eventHandlers.catch = callback;
return this;
};
// Here we wrap everything in a promise because
// - The code will wait one tick so that the functions that register our event handlers will be called first
// - We can catch all unhandled exceptions
Promise.resolve()
.then(() => {
// Run all events, start with the main one
mainEvent(function next(eventName, result) {
// Call the event handler and go on with the next event if there's a valid return value
if (
![undefined, false, null].includes(eventHandlers[eventName](result))
) {
events[eventName](next, eventHandlers.catch);
}
}, eventHandlers.catch);
})
.catch(eventHandlers.catch);
}
// Example code:
function myCustomPromiseChain() {
return new CustomPromiseChain({
// The main event will always be called at first
main(next, reject) {
// This will call the next event with a result
next('myEventOne', 'This is the result of event one.');
},
// Here you can register your other events:
myEventOne(next, reject) {
next('myEventTwo', 'This is the result of event two.');
},
myEventTwo(next, reject) {
next('myEventThree', 'This is the result of event three.');
},
myEventThree(next, reject) {
reject(new Error("I'm an error."));
},
});
}
myCustomPromiseChain()
.myEventOne((result) => {
console.log(`Result 1: ${result}`);
...