Guard Clause in Async
I really like Guard Clause, it makes me easier to read coding flow. Ya, you might want to google it “Guard Clause”, is a pattern to write code. You’ll end up on this link: Replace Nested Conditional with Guard Clauses - Refactoring. If you don’t use it or even don’t know it yet, I suggest you to learn and use it and share to your team. You all will love it.
But, when it comes to javascript, its always be exhausted. Javascript is exhausting. I dive in to async world in javascript two years ago and still don’t know to use Guard Clause in it. Ya, this code won’t work whatsoever:
1function getItem(type) {
2
3 if(type == 1) {
4 return request.get("/onetype", (err, results) => {
5 if(results.length) {
6 return null;
7 }
8
9 return results[0];
10 })
11 }
12
13 if(type == 2) {
14 return request.get("/another_type", (err, results) => {
15 if(results.length) {
16 return null;
17 }
18
19 return results[0];
20 })
21 }
22
23
24 return null;
25}
26
27let item = getItem(); // Won't return the desired item
So, how do we do that ? I don’t think we can do “Guard Clause” for async.
Lets take example for Martin Fowler website above, but in js.
1function getPayAmount() {
2 if (_isDead) return deadAmount();
3 if (_isSeparated) return separatedAmount();
4 if (_isRetired) return retiredAmount();
5 return normalPayAmount();
6};
If functions deadAmount, separatedAmount, retiredAmount and normalPayAmount are Promises, I used to do it like this.
1function getPayAmount(callback) {
2 if (_isDead) return deadAmount().then(callback);
3 if (_isSeparated) return separatedAmount().then(callback);
4 if (_isRetired) return retiredAmount().then(callback);
5 return normalPayAmount().then(callback);
6};
Ya but actually we can do it better like this.
1function getPayAmount() {
2 if (_isDead) return deadAmount();
3 if (_isSeparated) return separatedAmount();
4 if (_isRetired) return retiredAmount();
5 return normalPayAmount();
6};
7
8getPayAmount().then((amount) => {
9 // do whatever with amount
10});
Or better better, we can use IIFE if getPayAmount doesn’t necessary to be reusable function.
1(function getPayAmount() {
2 if (_isDead) return deadAmount();
3 if (_isSeparated) return separatedAmount();
4 if (_isRetired) return retiredAmount();
5 return normalPayAmount();
6};)()
7.then((amount) => {
8 // do whatever with amount
9})