diff --git a/JavaScript/5c-chain.js b/JavaScript/5c-chain.js new file mode 100644 index 0000000..0a1af28 --- /dev/null +++ b/JavaScript/5c-chain.js @@ -0,0 +1,63 @@ +const wrapAsync = + (fn) => + (...args) => + setTimeout(() => fn(...args), Math.random() * 1000); + +const readConfig = wrapAsync((data, callback) => { + console.log("data - ", data); + console.log("read config"); + + callback(null, data); +}); + +const selectFromDb = wrapAsync((query, callback) => { + console.log("query - ", query); + console.log("select from db"); + + callback(null, { cat: "Evgeniy" }); +}); + +const getHttpPage = wrapAsync((page, callback) => { + console.log("page - ", page); + console.log("Page retrieved"); + + callback(null, { page: "hello world!" }); +}); + +const chain = () => { + const stack = []; + + const executor = () => { + let result = () => null; + + const len = stack.length; + + for (let i = len - 1; i >= 0; i--) { + const [fn, args] = stack.pop(); + + const prev = result; + + result = (err, data) => { + if (err) return console.error({ err }); + fn(...args, prev); + }; + } + + result(); + }; + + executor.do = (cb, ...args) => { + stack.push([cb, args]); + + return executor; + }; + + return executor; +}; + +const startChain = chain() + .do(readConfig, "myConfig") + .do(selectFromDb, "select * from cities") + .do(getHttpPage, {}); + +startChain();