|
21 | 21 |
|
22 | 22 | Common built-in functions that are asynchronous and accept callback functions:
|
23 | 23 |
|
24 | | - * `setTimeout(function, delay)` |
| 24 | + * `setTimeout(func, delay)` |
25 | 25 |
|
26 | 26 | * `Event` mechanism
|
27 | 27 |
|
28 | | - Check out `async/1-callback/mylogger.js` |
| 28 | + Check out `src/async/1-callback/mylogger.js` |
29 | 29 |
|
30 | 30 | * Asynchronous requests (AJAX) with native `XMLHttpRequest` and `jQuery` `ajax()` method
|
31 | 31 |
|
|
39 | 39 |
|
40 | 40 | => <u>Chaining a lot of callback functions => "Callback hell (回调地狱)"</u>
|
41 | 41 |
|
42 | | - Check out `async/1-callback/fs_demo.js` as follows: |
| 42 | + Check out `src/async/1-callback/fs_demo.js` as follows: |
43 | 43 |
|
44 | 44 | ```javascript
|
45 | 45 | const fs = require('fs');
|
46 | 46 | const path = require('path');
|
47 | | - |
| 47 | + |
48 | 48 | const testFolderName = path.join(__dirname, 'test');
|
49 | 49 | const filename = path.join(testFolderName, 'hello.txt');
|
50 | | - |
| 50 | + |
51 | 51 | // In order to enture the correct execution order, we need to chain the
|
52 | 52 | // functions as callbacks, resulting in a long callback chain, which is referred
|
53 | 53 | // to as "callback hell".
|
54 | | - |
| 54 | + |
55 | 55 | // Create folder
|
56 | 56 | fs.mkdir(testFolderName, null, err => {
|
57 | 57 | if (err) throw err;
|
58 | 58 | console.log('Folder created.');
|
59 | | - |
| 59 | + |
60 | 60 | // Create file
|
61 | 61 | // (Equivalent to writing to file)
|
62 | 62 | fs.writeFile(filename, 'Hello, world!', err => {
|
63 | 63 | if (err) throw err;
|
64 | 64 | console.log('Data written.');
|
65 | | - |
| 65 | + |
66 | 66 | // Write (Append) to file
|
67 | 67 | fs.appendFile(filename, ' I love Node.js!', err => {
|
68 | 68 | if (err) throw err;
|
69 | 69 | console.log('Date appended.');
|
70 | | - |
| 70 | + |
71 | 71 | // Read file
|
72 | 72 | fs.readFile(filename, 'utf8', (err, data) => {
|
73 | 73 | if (err) throw err;
|
74 | 74 | console.log(`Read data: ${data}`);
|
75 | | - |
| 75 | + |
76 | 76 | // Rename file
|
77 | 77 | fs.rename(
|
78 | 78 | filename,
|
|
92 | 92 |
|
93 | 93 | * **`Promise` (since ES6 / ES2015)**
|
94 | 94 |
|
95 | | - * For usage, check out `src/async/2-promise/fetch_promise.js`, which contains the following code snippet, and https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/3-fetch-promise |
| 95 | + * For basic usage, check out `src/async/2-promise/fetch_demo.js`, which contains the following code snippet, and https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/3-promise-fetch |
96 | 96 |
|
97 | 97 | ```javascript
|
98 | 98 | const fetch = require('node-fetch');
|
99 | | - |
| 99 | + |
100 | 100 | // GET request
|
101 | 101 | fetch('https://jsonplaceholder.typicode.com/users')
|
102 | 102 | .then(response => response.json())
|
|
117 | 117 |
|
118 | 118 | ```javascript
|
119 | 119 | const fs = require('fs');
|
120 | | - |
| 120 | + |
121 | 121 | const somePath = 'test.txt';
|
122 | | - |
123 | | - function myExistHandler() { |
124 | | - console.log('File exists'); |
125 | | - } |
126 | | - |
127 | | - function myNotExistHandler(err) { |
128 | | - console.error(err); |
129 | | - } |
130 | | - |
| 122 | + |
| 123 | + const myExistHandler = () => console.log('File exists'); |
| 124 | + |
| 125 | + const myNotExistHandler = err => console.error(err); |
| 126 | + |
131 | 127 | // Originally, with callback functions, we would use "fs.exists()" like this:
|
132 | | - |
| 128 | + |
133 | 129 | function checkExistWithCallback(path, existHandler, notExistHandler) {
|
134 | 130 | fs.exists(path, exists => {
|
135 | 131 | if (exists) {
|
|
139 | 135 | }
|
140 | 136 | });
|
141 | 137 | }
|
142 | | - |
| 138 | + |
143 | 139 | checkExistWithCallback(somePath, myExistHandler, myNotExistHandler);
|
144 | | - |
| 140 | + |
145 | 141 | // In order to avoid "callback hell", we want to do the same thing with Promise
|
146 | 142 | // like this.
|
147 | | - |
| 143 | + |
148 | 144 | // checkExistsWithPromise(somePath)
|
149 | 145 | // .then(myExistHandler)
|
150 | 146 | // .catch(myNotExistHandler);
|
151 | | - |
| 147 | + |
152 | 148 | // If we want to the above, we must let "checkExistsWithPromise()" return a
|
153 | 149 | // Promise (in which we do the necessary work).
|
154 | | - |
| 150 | + |
155 | 151 | function checkExistsWithPromise(path) {
|
156 | 152 | return new Promise((resolve, reject) => {
|
157 | 153 | fs.exists(path, exists => {
|
|
163 | 159 | });
|
164 | 160 | });
|
165 | 161 | }
|
166 | | - |
| 162 | + |
167 | 163 | checkExistsWithPromise(somePath)
|
168 | 164 | .then(myExistHandler)
|
169 | 165 | .catch(myNotExistHandler);
|
170 | 166 | ```
|
171 | 167 |
|
172 | | - * For advantage usage of Promises, including <u>sequential execution (chaining) of multiple Promises</u>, or <u>parallel execution</u>, check out `async/2-promise/promise_advanced.js` as follows: |
| 168 | + * For advantage usage of Promises, including <u>sequential execution (chaining) of multiple Promises</u>, or <u>parallel execution</u>, check out `src/async/2-promise/promise_advanced.js` as follows: |
173 | 169 |
|
174 | 170 | ```javascript
|
175 | 171 | const { cleanRoom, removeGarbage, winIceCream } = require('../common');
|
176 | | - |
| 172 | + |
177 | 173 | console.log('With asynchronous programming, this line is printed first.');
|
178 | | - |
179 | | - // Sequential execution (chaining) |
| 174 | + |
| 175 | + // ===== Sequential execution (chaining) ===== |
180 | 176 | cleanRoom()
|
181 | 177 | .then(msg => {
|
182 | 178 | console.log(msg);
|
|
191 | 187 | console.log('All finished');
|
192 | 188 | })
|
193 | 189 | .catch(err => console.log(err));
|
194 | | - |
195 | | - // Parallel execution |
| 190 | + |
| 191 | + // ===== Parallel execution ===== |
196 | 192 | Promise.all([cleanRoom(), removeGarbage(), winIceCream()])
|
197 | 193 | .then(values => {
|
198 | 194 | console.log(values);
|
|
224 | 220 |
|
225 | 221 | ***
|
226 | 222 |
|
227 | | - 这个syntax sugar是我们对于error handling, 不必再使用`.catch()`方法, 而是可以恢复到传统的synchronous programming的`try/catch`. |
| 223 | + 这个syntax sugar使我们对于error handling, 不必再使用`.catch()`方法, 而是可以恢复到传统的synchronous programming的`try/catch`. |
228 | 224 |
|
229 | | - * For usage, check out `src/async/3-async-await/fetch_async_await.js`, which contains the following code snippet, and https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/4-fetch-async-await |
| 225 | + * For usage, check out `src/async/3-promise-async-await/fetch_async_await_demo.js`, which contains the following code snippet, and https://github.com/Ziang-Lu/JavaScript-Learning-Notes/tree/master/ajax/4-promise-fetch-async-await |
230 | 226 |
|
231 | 227 | ```javascript
|
232 | 228 | /**
|
233 | 229 | * Same thing as "fetch_promise.js", but with "async/await" syntax sugar.
|
234 | 230 | */
|
235 | | - |
| 231 | + |
236 | 232 | const fetch = require('node-fetch');
|
237 | | - |
| 233 | + |
238 | 234 | // fetch()-API returns a Promise
|
239 | | - |
| 235 | + |
240 | 236 | // GET request
|
241 | 237 | async function fetchUsers() {
|
242 | 238 | // This "async" function returns a Promise
|
243 | | - |
244 | 239 | try {
|
245 | 240 | const response = await fetch('https://jsonplaceholder.typicode.com/users');
|
246 | 241 | const users = await response.json(); // response.json() also returns a Promise
|
|
257 | 252 | }
|
258 | 253 | console.log();
|
259 | 254 | }
|
260 | | - |
| 255 | + |
261 | 256 | fetchUsers();
|
262 | 257 | ```
|
263 | 258 |
|
264 | | -* For usage of Promises with `async/await` syntax sugar, check out `async/3-async-await/promise_async_await.js` as follows: |
| 259 | +* For usage of Promises with `async/await` syntax sugar, check out `src/async/3-promise-async-await/promise_async_await.js` as follows: |
265 | 260 |
|
266 | 261 | ```javascript
|
267 | 262 | const { cleanRoom, removeGarbage, winIceCream } = require('../common');
|
268 | | - |
269 | | - // Sequential execution (chaining) |
| 263 | + |
| 264 | + // ===== Sequential execution (chaining) ===== |
270 | 265 | async function myRoutine() {
|
271 | 266 | // This "async" function returns a Promise
|
272 | | - |
273 | 267 | try {
|
274 | 268 | let msg = await cleanRoom();
|
275 | 269 | console.log(msg);
|
|
282 | 276 | console.error(err);
|
283 | 277 | }
|
284 | 278 | }
|
285 | | - |
| 279 | + |
286 | 280 | myRoutine();
|
287 | | - |
| 281 | + |
288 | 282 | // 使得程序looks and feels like synchronous, 虽然实际上只是syntax sugar, under the
|
289 | 283 | // hood还是asynchronous
|
290 | | - |
291 | | - // Parallel execution |
| 284 | + |
| 285 | + // ===== Parallel execution ===== |
292 | 286 | async function myRoutineParallel() {
|
293 | 287 | // This "async" function returns a Promise
|
294 | | - |
295 | 288 | try {
|
296 | 289 | const messages = await Promise.all([
|
297 | 290 | cleanRoom(),
|
|
304 | 297 | console.error(err);
|
305 | 298 | }
|
306 | 299 | }
|
307 | | - |
| 300 | + |
308 | 301 | myRoutineParallel();
|
309 | 302 | ```
|
310 | 303 |
|
@@ -333,7 +326,7 @@ Node installations and versions are managed by NVM (Node Version Manager).
|
333 | 326 |
|
334 | 327 | ```bash
|
335 | 328 | $ nvm install node # Install the latest version
|
336 | | - |
| 329 | + |
337 | 330 | # Verify that Node has been installed:
|
338 | 331 | $ nvm which current
|
339 | 332 | # /Users/Ziang_Lu/.nvm/versions/node/v13.5.0/bin/node
|
|
0 commit comments