Skip to content

Commit 44289a2

Browse files
committed
convert callback to async-await directly
1 parent 96aad77 commit 44289a2

File tree

3 files changed

+95
-27
lines changed

3 files changed

+95
-27
lines changed

Promise-Async-Await-Sequential-Execution/Promise-async-await-master-notes/README.md

+22-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#### A promise is an object that wraps an asynchronous operation and notifies when it’s done. This sounds exactly like callbacks, but the important differences are in the usage of Promises. Instead of providing a callback, a promise has its own methods (.then) which you call to tell the promise what will happen when it is successful or when it fails. The methods a promise provides are “then(…)” for when a successful result is available and “catch(…)” for when something went wrong.
22

3+
In other words, **When we call a Promise function, the result from the successful path will show up in the .then(), while the error scenario will show up in the .catch()**
4+
35
#### It takes 2 arguments and both are callback functions. The first one is for the fullfilment case and the socond one is for the rejection case.
46

57
#### Promise in JS means, just as the word meaning, i.e. its not the value itself, but its the promise of a value.
@@ -9,38 +11,32 @@
911
Promises provide a simpler alternative for executing, composing, and managing asynchronous operations when compared to traditional callback-based approaches. They also allow you to handle asynchronous errors using approaches that are similar to synchronous try/catch.
1012
Promise is basically just an object with 2 functions. A) A function named then() whcih is called anytime the promise is successful, and B) catch() function, which is called anytime something bad has happened.
1113

12-
### All promise instances get a then method which allows you to react to the promise. The first then method callback receives the result given to it by the resolve() call: The then method on the promise object adds handlers for the resolved and rejected states. This function returns another promise object to allow for promise-pipelining, enabling the developer to chain together async operations where the result of the first operation will get passed to the second.
13-
14+
### All promise instances get a then method which allows you to react to the promise. The first then method callback receives the result given to it by the resolve() call: The then method on the promise object adds handlers for the resolved and rejected states. This function returns another promise object to allow for promise-pipelining, enabling the developer to chain together async operations where the result of the first operation will get passed to the second.
1415

1516
Promises have a then method, which you can use to get the eventual return value (fulfillment) or thrown exception (rejection).
1617

1718
```js
18-
promiseMeSomething()
19-
.then(function (value) {
20-
}, function (reason) {
21-
});
19+
promiseMeSomething().then(function(value) {}, function(reason) {});
2220
```
2321

24-
``then(resolvedHandler, rejectedHandler); ``
22+
`then(resolvedHandler, rejectedHandler);`
2523

2624
If promiseMeSomething returns a promise (remember that 'then' method returns a promise) that gets fulfilled later with a return value, the first function (the fulfillment handler) will be called with the value. However, if the promiseMeSomething function gets rejected later by a thrown exception, the second function (the rejection handler) will be called with the exception.
2725

2826
Note that resolution of a promise is always asynchronous: that is, the fulfillment or rejection handler will always be called in the next turn of the event loop (i.e. process.nextTick in Node). This gives you a nice guarantee when mentally tracing the flow of your code, namely that then will always return before either handler is executed.
2927

3028
```js
3129
new Promise(function(resolve, reject) {
32-
// A mock async action using setTimeout
33-
setTimeout(() => resolve(10), 1000);
34-
})
35-
.then((result) => {
36-
console.log(result);
30+
// A mock async action using setTimeout
31+
setTimeout(() => resolve(10), 1000);
32+
}).then(result => {
33+
console.log(result);
3734
});
3835

3936
// Outputs 10 after 1000 ms
40-
4137
```
4238

43-
### The then callback is triggered when the promise is resolved. You can also chain then method callbacks:
39+
### The then callback is triggered when the promise is resolved. You can also chain then method callbacks:
4440

4541
```js
4642
new Promise(function(resolve, reject) {
@@ -66,19 +62,21 @@ Second then: 20
6662
Third then: 40
6763

6864
```
65+
6966
### Each then receives the result of the previous then's return value. If a promise has already resolved but then is called again, the callback immediately fires. If the promise is rejected and you call then after rejection, the callback is never called.
7067

7168
If you return a value, the next "then" is called with that value. However, if you return something promise-like, the next "then" waits on it, and is only called when that promise settles (succeeds/fails)
7269

7370
```js
74-
fetchData().
75-
then(prepareDataForCsv).
76-
then(writeToCsv).
77-
then(function () {
78-
console.log('your csv has been saved');
79-
}).catch(function (error) {
80-
console.log('something went wrong', error);
81-
});
71+
fetchData()
72+
.then(prepareDataForCsv)
73+
.then(writeToCsv)
74+
.then(function() {
75+
console.log("your csv has been saved");
76+
})
77+
.catch(function(error) {
78+
console.log("something went wrong", error);
79+
});
8280
```
8381

8482
## Because of how the chaining of promises and errors work, as discussed earlier, it means that just one catch at the end of the chain is guaranteed to catch any errors thrown along the way. This makes error handling really straight forward.
@@ -93,7 +91,7 @@ A> http://farzicoder.com/Callback-Hell-Promises-generators-Async-Await-in-Node-j
9391

9492
https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261
9593

96-
Because ``.then()`` always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled. Promises allow you to mimic normal synchronous code’s try/catch behavior.
94+
Because `.then()` always returns a new promise, it’s possible to chain promises with precise control over how and where errors are handled. Promises allow you to mimic normal synchronous code’s try/catch behavior.
9795

9896
Like synchronous code, chaining will result in a sequence that runs in serial. In other words, you can do:
9997

@@ -104,4 +102,4 @@ fetch(url)
104102
.catch(handleErrors);
105103
```
106104

107-
Assuming each of the functions, fetch(), process(), and save() return promises, process() will wait for fetch() to complete before starting, and save() will wait for process() to complete before starting. handleErrors() will only run if any of the previous promises reject.
105+
Assuming each of the functions, fetch(), process(), and save() return promises, process() will wait for fetch() to complete before starting, and save() will wait for process() to complete before starting. handleErrors() will only run if any of the previous promises reject.

Promise-Async-Await-Sequential-Execution/async-await-master-notes/converting-callback-to-Promise-and-async-await.md

+73-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ A Promise-based API for this function would likely look something like this code
1616

1717
We can create an API like that using setTimeout. To do that, we’ll need a function timeout which takes a timeout variable and returns a Promise.
1818

19-
You can define A+ compliant Promises using the Promise constructor, which expects a single function as an argument. That function takes 2 arguments, a resolve function and a reject function. The wonderful thing is that under the covers these are just callback functions that the Promise api glosses over.
19+
You can define A+ compliant Promises using the Promise constructor, which expects a single function as an argument. That function takes 2 arguments (both are callbacks), a resolve function and a reject function. The wonderful thing is that under the covers these are just callback functions that the Promise api glosses over.
2020

2121
```js
2222
function timeout(delay) {
@@ -32,7 +32,7 @@ We don’t use the reject callback, since setTimeout doesn’t provide any hooks
3232

3333
[Source Code](https://github.com/coreyc/converting-callbacks/blob/master/index.js)
3434

35-
#### Callback version
35+
### Callback version
3636

3737
```js
3838
const callbackFn = (firstName, callback) => {
@@ -53,7 +53,7 @@ We're using the setTimeout() function in order to make our function asynchronous
5353

5454
In this function, we "reject" it if the first name argument is null. When we do pass in the firstName argument, the callback function (almost always the last argument in a callback-based function's argument list) gets called and returns our value after the 2 seconds set in setTimeout().
5555

56-
#### Promise version - And here's the Promise-based version of that function:
56+
### Promise version - And here's the Promise-based version of that function:
5757

5858
```js
5959
const promiseFn = firstName => {
@@ -76,6 +76,76 @@ Converting to a Promise-based function is actually pretty simple. Look at the be
7676

7777
<img src="convert-callback-to-promise-async-await-1.png">
7878

79+
First, we remove the callback argument. Then we add the code to return a new Promise from our Promise-based function. The error callback becomes a reject, while the "happy path" callback becomes a resolve.
80+
81+
Remember, Promise expects a single function as an argument. That function takes 2 arguments (both are callbacks), a resolve function and a reject function.
82+
83+
**When we call the promiseFn, the result from the happy path will show up in the .then(), while the error scenario will show up in the .catch()**
84+
85+
The great thing about having our function in Promise form is that we don't actually need to "make it an async/await version" if we don't want to. When we call/execute the function, we can simply use the async/await keyword, like so:
86+
87+
(Remember - **Await works only with Promises, it does not work with callbacks. So to implement async-await to a function/code, I first have to convert the callback to a Promise **)
88+
89+
```js
90+
const result = (async () => {
91+
try {
92+
console.log(await promiseFn("Jim"));
93+
} catch (e) {
94+
console.log(e);
95+
}
96+
97+
try {
98+
console.log(await promiseFn());
99+
} catch (e) {
100+
console.log(e);
101+
}
102+
})();
103+
```
104+
105+
Side note: here I wrapped the function call in an IIFE (IIFE = "Immediately Invoked Function Execution") This is simply because we need to wrap the await call in a function that uses the async keyword. Here, there are no callbacks, no .then()'s or .catch()'s, we just use a try/catch block and call the promiseFn(). Promise rejections will be caught by the catch block.
106+
107+
### async/await version
108+
109+
But what if we wanted to convert a callback function directly to an async/await version of that function? Without using Promises directly?
110+
111+
```js
112+
const timeout = ms => {
113+
return new Promise(resolve => setTimeout(resolve, ms));
114+
};
115+
116+
const asyncAwaitFn = async firstName => {
117+
await timeout(2000); // using timeout like this makes it easier to demonstrate callback -> async/await conversion
118+
119+
if (!firstName) throw new Error("no first name passed in!");
120+
121+
const fullName = `${firstName} Doe`;
122+
123+
return fullName;
124+
};
125+
126+
const res = (async () => {
127+
try {
128+
console.log(await asyncAwaitFn("Jack"));
129+
} catch (e) {
130+
console.log(e);
131+
}
132+
133+
try {
134+
console.log(await asyncAwaitFn());
135+
} catch (e) {
136+
console.log(e);
137+
}
138+
})();
139+
```
140+
141+
Use the below diagram to understand how to go from callback to async
142+
143+
<img src="convert-callback-to-async-await-directly.png">
144+
145+
Similar to converting to the Promise-based version, we get rid of the callback passed in to the original function, as well as that argument call within the body of the function. Next, we add the async keyword to the beginning of the function declaration. And finally, when we hit the error scenario, we throw an Error, which results in a rejected Promise (caught in the catch block when we call the function), and simply return the fullName in the happy path scenario.
146+
147+
Note that async functions all return Promises, so when you use return you are just resolving the Promise.
148+
79149
#### Further reading
80150

81151
1> https://benmccormick.org/2015/12/30/es6-patterns-converting-callbacks-to-promises

0 commit comments

Comments
 (0)