triston-notes/Cards/dev/Js promise handeler.md
2023-10-21 18:52:54 -05:00

100 lines
2.4 KiB
Markdown

---
banner: "https://media.discordapp.net/attachments/1050995657797816341/1091278921972064336/Triston_control_flow_a42cae90-667c-465d-9112-8104d61d0533.png?width=1856&height=1040"
---
up:: [[JavaScript]]
tags::
## The Problem
The Try/Catch flow can get really hairy with multiple requests becoming many lines of logic, like so:
```js
let res1
try{
res1 = await request1()
}catch(e){
// handle some error
}
let res2
try{
res2 = await request2()
}catch(e){
// handle some error
}
let res3
try{
res3 = await request3()
}catch(e){
// handle some error
}
```
As well as the promise chaining can get nasty as well, like so:
```js
request1().then(res => {
requst2().then(res => {
requst3().then(res => {
// do something
}).catch(e => console.error(e))
}).catch(e=>console.error(e))
}).catch(e => console.error(e))
```
#### not ideal.. But theres a solution, that isnt my idea but i wanted to note it
---
## The solution
We can create a single function that acts as a wrapper for the request and return a dictionary of value and error, like so:
```js
export default async function result(cb){
let result = { value: null, error: null };
try {
const r = await cb();
result.value = r;
} catch (error) {
result.error = error;
}
return result;
}
```
and we can now use this function like so:
```js
const {value, error} = await result(request1)
```
we dont need to wrap this in a try/catch because it will not fail
And we can even alias the error and value if needing to make multiple async calls
```js
const {value: aVal, error: aErr} = await result(request1)
const {value: bVal, bErr} = await result(request2)
const {value: cVal, cErr} = await result(request3)
```
Well, what if we need to pass `aVal` to `request2`
EASY
```js
const {value: aVal, error: aErr} = await result(request1)
const {value: bVal, bErr} = await result(async () => await request2(aVal))
const {value: cVal, cErr} = await result(async () => await request3(bVal))
```
And what if we need to control flow, maybe early return?
Again, EASY
```js
const {value: aVal, error: aErr} = await result(request1)
if (aErr) return
const {value: bVal, bErr} = await result(async () => await request2(aVal))
if (!bVal) return
const {value: cVal, cErr} = await result(async () => await request3(bVal))
if (!cErr) return cVal
if (cErr) return "whole thing failed"
```
---
## Types
Maybe we're using typescript and want to make this all type safe, cause right now, we know nothing