Created
September 15, 2023 18:53
-
-
Save tonylampada/16639ddfd2f1c12cbc5d92b4b1df9175 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
// web framework | |
function webapp() { | |
return { | |
handlers: {}, | |
addRoute(route, fn){ | |
this.handlers[route] = fn; | |
}, | |
async exec(route, params){ | |
const handler = this.handlers[route]; | |
if (!handler) { | |
return {status: 404, body: `route not found: ${route}`} | |
} | |
return new Promise(async (resolve) => { | |
try { | |
await handler(params, {send: ({status, body}) => { | |
status = status || 200; | |
body = body || "OK" | |
resolve({status, body}); | |
}}) | |
} catch (err) { | |
console.error(`[REQUEST ERROR] - ${route} with params ${params}`, err) | |
resolve({status: 500, body: "unknown error"}) | |
} | |
}) | |
} | |
} | |
} | |
// helper "asyncify" | |
async function sleep(ms) { | |
// async pause, for dramatic purposes | |
return new Promise((r) => setTimeout(r, ms)); | |
} | |
// backend services | |
const services = { | |
async loadFooFromDatabase(id) { | |
await sleep(300) | |
return {id, name: "foo"}; | |
}, | |
async saveFooToStorage(foo, filename) { | |
await sleep(300); | |
const fooData = {id: foo.id, Name: foo.Name, size: foo.Name.length}; | |
console.log(`storage pretend save: ${JSON.stringify(fooData)}`) | |
const storageId = parseInt(Math.random() * 1E10); | |
return storageId; | |
}, | |
async scheduleFooTransfer(storageId) { | |
await sleep(300); | |
console.log(`fake pubsub call with storageId ${storageId}`) | |
const messageId = parseInt(Math.random() * 1E10); | |
return messageId | |
} | |
} | |
// my app | |
const myapp = webapp(); | |
myapp.addRoute('/save/foo', savefoo1) | |
myapp.addRoute('/save/foo2', savefoo2) | |
function savefoo1(params, res) { | |
const {id} = params; | |
// ugly code style | |
// risk losing track of the stack | |
// by throwing exceptions into the void | |
services.loadFooFromDatabase(id).then(foo => { | |
services.saveFooToStorage(foo, `/path/to/foo/${foo.id}`).then(storageId => { | |
services.scheduleFooTransfer(storageId).then(messageId => { | |
console.log(`finished processing foo ${id}. MessageID = ${messageId}`) | |
res.send({status: 200, body: `OK - foo processed ${id}`}) | |
}) | |
}) | |
}) | |
} | |
async function savefoo2(params, res) { | |
const {id} = params; | |
const foo = await services.loadFooFromDatabase(id) | |
const storageId = await services.saveFooToStorage(foo, `/path/to/foo/${foo.id}`) | |
const messageId = await services.scheduleFooTransfer(storageId) | |
console.log(`finished processing foo ${id}. MessageID = ${messageId}`) | |
res.send({status: 200, body: `OK - foo processed ${id}`}) | |
} | |
module.exports = myapp | |
// r1 = await myapp.exec('/save/foo', {id: 3}) | |
// r2 = await myapp.exec('/save/foo2', {id: 3}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you're wondering what was the "right" way to solve that problem in the world before async/await,
This is the "right" way to chain promises, so that you can still have a catch-all after them:
https://gist.github.com/tonylampada/192442087b3830d4c7e7698e0d3daaab
It's better than the wrong way, but with async/await it's probably not even worth teaching it :-)