Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit e69af25

Browse files
committed
callbacks done
1 parent 5bc5913 commit e69af25

File tree

1 file changed

+223
-0
lines changed

1 file changed

+223
-0
lines changed

‎12-Asynchronous-JavaScript.md

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
# Understanding Asynchronous JavaScript
2+
3+
JavaScript is single-threaded programming language which means only one thing can happen at a time. This helps us to simplify our code but this also means that we can't perform long operations such as reading from a file without blocking the main thread. That's where asynchronous JavaScript helps us.
4+
5+
Asynchronous JavaScript helps us to perform tasks without having to wait for a pervious task to complete, which results in a faster and more efficient code execution. When we use asynchronous programming, the browser will continue to render the page while the task is running in the background. This means that the user will not have to wait for the task to finish before they can interact with the webpage.
6+
7+
Before we dive into asynchronous JavaScript, we need to first understand how synchronous JavaScript gets executed by JavaScript engine.
8+
9+
_Reminder:_
10+
11+
```
12+
**Execution Context**: abstract concept of environment where JavaScript code is evaluated and executes.
13+
14+
**Call Stack**: used to store all the execution context created during the code execution.
15+
```
16+
17+
Let us consider a example.
18+
19+
```js
20+
const second = () => {
21+
console.log("This is second function.")
22+
}
23+
24+
const first = () => {
25+
console.log("This is first function.")
26+
second();
27+
console.log("End);
28+
}
29+
30+
first();
31+
```
32+
33+
When this code is executed, a gloval execution context `main()` is created and pushed to the top of call stack.
34+
35+
```
36+
| |
37+
| |
38+
| main() |
39+
|___________|
40+
```
41+
42+
The `first` and `second` functions are then added to the global memory. The `first` function is called within the main function and the cal to `first` function is added to the top of call stack.
43+
44+
```
45+
| |
46+
| `first()` |
47+
|___________|
48+
```
49+
50+
The `first` function is executed and logs "I am the first function." to the console. The `second()` is called within the `first` function so, the `second()` is added to the top of the call stack.
51+
52+
```
53+
| |
54+
| second() |
55+
| first() |
56+
|___________|
57+
```
58+
59+
The `second` function is also executed and logs "This is the second fucntion." to the console. The call to the `second()` is then removed form the call stack.
60+
61+
```
62+
| |
63+
| |
64+
| first() |
65+
|___________|
66+
```
67+
68+
The `first` function then logs "End" to the console and the call to the `first` function is also removed from the call stack. The `main()` function or global execution context finishes executing and is removed from the stack.
69+
70+
```
71+
Note: Call Stack is Last In, First Out (LIFO) data structure, that means that the last function to be added to the stack is the first one to be removed.
72+
```
73+
74+
**_Problem caused by Synchronous behavior of JavaScript:_**
75+
76+
One common problem caused by this synchronous behavior of JavaScript is that it can block the browser's user interface and make it unresponsive. This happens when a time-consuming tasks such as fetching data from server is executed synchronously on the main thread.
77+
78+
```js
79+
const processImage = (img) => {
80+
console.log("Processing " + img);
81+
};
82+
83+
const downloadImage = (url) => {
84+
setTimeout(() => {
85+
console.log("Downloading Image from " + url);
86+
}, 2000);
87+
};
88+
89+
downloadImage("www.someimage.com");
90+
processImage("Poo.jpg");
91+
```
92+
93+
_Output:_
94+
95+
```
96+
Processing Poo.jpg
97+
Downloading Image from www.someimage.com
98+
```
99+
100+
This is something we do not expect because the `process()` function gets executed before the `download()` function. We would expect image to be downloaded before we process it.
101+
102+
To avoid such problems, we can use asynchrnous programming concepts such as `callbacks`, `promises`, and `async/await` to allow long-running tasks to be executed in the background without blocking the UI.
103+
104+
**_So, How does Asynchronous JavaScript work?_**
105+
106+
## Callbacks
107+
108+
We can pass a fucntion to another function as an argument in JavaScript. By definition, `callback` is a function that we pass into another function as an argument for executing later when the execution of first function is completed.
109+
110+
Let us consider an example where a function accepts an array of number as argument and returns a new array of odd numbers.
111+
112+
```js
113+
function filterOdd(numbers) {
114+
let results = [];
115+
for (const number of numbers) {
116+
if (number % 2 != 0) {
117+
results.push(number);
118+
}
119+
}
120+
return results;
121+
}
122+
123+
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
124+
console.log(filterOdd(numbers)); // Output: [1,3,5,7,9]
125+
```
126+
127+
In this example, we have a function that accpets an array of numbers and returns new array of odd numbers. But if we want to return an array of even numbers, we now need to modify the `filterOdd` function. This is not an ideal condition.
128+
129+
We need to make our function more generic and resuable. We can do so by extracting the logic in `if` block and wrap it in a new function and pass the `filter` function as an argument.
130+
131+
```js
132+
function isOdd(number) {
133+
return number % 2 !== 0;
134+
}
135+
136+
function filter(numbers, callback) {
137+
let results = [];
138+
for (const number of numbers) {
139+
if (callback(number)) {
140+
results.push(number);
141+
}
142+
}
143+
return results;
144+
}
145+
146+
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
147+
console.log(filter(numbers, isOdd)); // Output: [1,3,5,7,9]
148+
```
149+
150+
We get the same output as previous one but now with the updated code, we can pass any function that accepts an argument and returns a boolean value to the second argument of the `filter` function.
151+
152+
For example, we can now use this `filter` function to return an array of even numbers too.
153+
154+
```js
155+
function isOdd(number) {
156+
return number % 2 !== 0;
157+
}
158+
159+
function isEven(number) {
160+
return number % 2 === 0;
161+
}
162+
163+
function filter(numbers, callback) {
164+
let results = [];
165+
for (const number of numbers) {
166+
if (callback(number)) {
167+
results.push(number);
168+
}
169+
}
170+
return results;
171+
}
172+
173+
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9];
174+
175+
console.log(filter(numbers, isOdd)); // Output: [1,3,5,7,9]
176+
console.log(filter(numbers, isEven)); // Ouput: [2,4,6,8]
177+
```
178+
179+
Here, `isOdd` and `isEven` are callback functions or callbacks.
180+
181+
### Synchronous Callbacks
182+
183+
Synchronous callbacks is a callback function that is exeucuted immediately when it is called, blocking the main thread until it completes. Synchronous callbacks are executed in the same order as they are called, and they can cause the program to become unresponsive if they take too long to complete.
184+
185+
The `isOdd` and `isEven` are examples of synchronous function because they execute immediately during the execution of `filter()` function.
186+
187+
### Asynchronous Callbacks
188+
189+
Asynchronous callbacks are the functions that are executed after the execution of high-order function that uses the callback. This allows us to write a non-blocking code that will execute the rest of the code if it has to wait for certain operation to complete. This helps us to execute long-running operations without freezing the UI or blocking the execution of other code.
190+
191+
Let us consider example from previous where we wrote a program to download a picture and process it. Downloading a picture takes time depending upon the speed and size of the picture. This may halt or slow down our program as we seen before.
192+
193+
To resolcve such issues, we can update our code as below -
194+
195+
```js
196+
function downloadImage(url, callback) {
197+
setTimeout(() => {
198+
// download image
199+
console.log("Downloading image from " + url);
200+
// process image after download
201+
callback(url);
202+
}, 1000);
203+
}
204+
205+
function process(picture) {
206+
console.log("Processing " + picture);
207+
}
208+
209+
downloadImage("www.someimage.com/foo.jpg", process);
210+
```
211+
212+
_Output:_
213+
214+
```
215+
Downloading image from www.someimage.com/foo.jpg
216+
Processing www.someimage.com/foo.jpg
217+
```
218+
219+
In this example, we call the `downloadImage` function with a URL and a `process()` callback function which downloads the image from the URL. However, downloading an image can take some time, so we don't want the function to block the execution of the code. Therefore, we set a timeout of 1 second (1000 milliseconds) to `downloadImage()` function.
220+
221+
Once the image is downloaded, the `callback` function is called with the url of the downloaded image as an argument. In this case, the `callback` fucntion is the `process` function. The `process` function is executed asynchronously, after the image is downlaoded and the `callback` fucntion is called.
222+
223+
_Note_: `setTimeout` is not a part of JavaScript engine but it is a part of Web APIs (in browsers).

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /