Skip to content

Commit aee3c2b

Browse files
committed
back to in chinese & add the new part of generators and async await
1 parent e561e9f commit aee3c2b

File tree

1 file changed

+148
-12
lines changed

1 file changed

+148
-12
lines changed

README_zhCn.md

Lines changed: 148 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
- [Maps](#maps)
1818
- [WeakMaps](#weakmaps)
1919
- [Promises](#promises)
20+
- [Generators](#generators)
21+
- [Async Await](#async-await)
2022

2123
## var versus let / const
2224

@@ -67,7 +69,7 @@ let x = 'hi'; // ReferenceError: x is not defined
6769

6870
> **最佳实践**: 在重构老代码时,`var` 声明需要格外的注意。在创建一个新项目时,使用 `let` 声明一个变量,使用 `const` 来声明一个不可改变的常量。
6971
70-
<sup>[(back to table of contents)](#table-of-contents)</sup>
72+
<sup>[(回到目录)](#table-of-contents)</sup>
7173

7274
## Replacing IIFEs with Blocks
7375

@@ -92,7 +94,7 @@ console.log(food); // Reference Error
9294
console.log(food); // Reference Error
9395
```
9496

95-
<sup>[(back to table of contents)](#table-of-contents)</sup>
97+
<sup>[(回到目录)](#table-of-contents)</sup>
9698

9799
## Arrow Functions
98100

@@ -181,7 +183,7 @@ const squares = arr.map(x => x * x); // Arrow Function for terser implementation
181183

182184
> **最佳实践**:尽可能地多使用 **箭头函数**
183185
184-
<sup>[(back to table of contents)](#table-of-contents)</sup>
186+
<sup>[(回到目录)](#table-of-contents)</sup>
185187

186188
## Strings
187189

@@ -291,7 +293,7 @@ let today = new Date();
291293
let text = `The time and date is ${today.toLocaleString()}`;
292294
```
293295

294-
<sup>[(back to table of contents)](#table-of-contents)</sup>
296+
<sup>[(回到目录)](#table-of-contents)</sup>
295297

296298
## Destructuring
297299

@@ -318,7 +320,7 @@ console.log(b); // 2
318320

319321
### Destructuring Objects
320322

321-
**结构对象**
323+
**解构对象**
322324

323325
```javascript
324326
var luke = { occupation: 'jedi', father: 'anakin' };
@@ -334,7 +336,7 @@ console.log(occupation); // 'jedi'
334336
console.log(father); // 'anakin'
335337
```
336338

337-
<sup>[(back to table of contents)](#table-of-contents)</sup>
339+
<sup>[(回到目录)](#table-of-contents)</sup>
338340

339341
## Modules
340342

@@ -458,7 +460,7 @@ const { Component, PropTypes } = React;
458460
> **注意**:被导出的值是被 **绑定的(原文:bingdings)**,而不是引用。
459461
所以,改变一个模块中的值的话,会影响其他引用本模块的代码,一定要避免此种改动发生。
460462

461-
<sup>[(back to table of contents)](#table-of-contents)</sup>
463+
<sup>[(回到目录)](#table-of-contents)</sup>
462464

463465
## Parameters
464466

@@ -553,7 +555,7 @@ function initializeCanvas(
553555
Math.max(...[-1, 100, 9001, -32]); // 9001
554556
```
555557

556-
<sup>[(back to table of contents)](#table-of-contents)</sup>
558+
<sup>[(回到目录)](#table-of-contents)</sup>
557559

558560
## Classes
559561

@@ -623,7 +625,7 @@ class Personal extends Person {
623625

624626
> **最佳实践**:ES6新的类语法把我们从晦涩难懂的实现和原型操作中解救出来,这是个非常适合初学者的功能,而且能让我们写出更干净整洁的代码。
625627
626-
<sup>[(back to table of contents)](#table-of-contents)</sup>
628+
<sup>[(回到目录)](#table-of-contents)</sup>
627629

628630
## Symbols
629631

@@ -643,7 +645,7 @@ object[keyTwo] = 'Much Uniqueness';
643645
>> false
644646
```
645647

646-
<sup>[(back to table of contents)](#table-of-contents)</sup>
648+
<sup>[(回到目录)](#table-of-contents)</sup>
647649

648650
## Maps
649651

@@ -700,10 +702,11 @@ for (let [key, value] of map.entries()) {
700702
}
701703
```
702704

703-
<sup>[(back to table of contents)](#table-of-contents)</sup>
705+
<sup>[(回到目录)](#table-of-contents)</sup>
704706

705707
## WeakMaps
706708

709+
707710
In order to store private data in < ES5, we had various ways of doing this.
708711
One such method was using naming conventions:
709712

@@ -771,7 +774,7 @@ value = map.get(el); // undefined
771774
> **提示**:结合这个例子,再考虑下jQuery是如何实现缓存带有引用的DOM元素这个功能的,使用了WeakMaps的话,当被缓存的DOM元素被移除的时,jQuery可以自动释放相应元素的内存。
772775
通常情况下,在涉及DOM元素存储和缓存的情况下,使用WeakMaps是非常适合的。
773776

774-
<sup>[(back to table of contents)](#table-of-contents)</sup>
777+
<sup>[(回到目录)](#table-of-contents)</sup>
775778

776779
## Promises
777780

@@ -849,3 +852,136 @@ Promise.all(urlPromises)
849852
console.log('Failed: ', err);
850853
});
851854
```
855+
856+
<sup>[(回到目录)](#table-of-contents)</sup>
857+
858+
## Generators
859+
860+
Similar to how [Promises](https://github.com/DrkSephy/es6-cheatsheet#promises) allow us to avoid
861+
[callback hell](http://callbackhell.com/), Generators allow us to flatten our code - giving our
862+
asynchronous code a synchronous feel. Generators are essentially functions which we can
863+
[pause their excution](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield)
864+
and subsequently return the value of an expression.
865+
866+
A simple example of using generators is shown below:
867+
868+
```javascript
869+
function* sillyGenerator() {
870+
yield 1;
871+
yield 2;
872+
yield 3;
873+
yield 4;
874+
}
875+
876+
var generator = sillyGenerator();
877+
var value = generator.next();
878+
> console.log(value); // { value: 1, done: false }
879+
> console.log(value); // { value: 2, done: false }
880+
> console.log(value); // { value: 3, done: false }
881+
> console.log(value); // { value: 4, done: false }
882+
```
883+
884+
Where [next](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next)
885+
will allow us to push our generator forward and evaluate a new expression. While the above example is extremely
886+
contrived, we can utilize Generators to write asynchronous code in a synchronous manner:
887+
888+
```javascript
889+
// Hiding asynchronousity with Generators
890+
891+
function request(url) {
892+
getJSON(url, function(response) {
893+
generator.next(response);
894+
});
895+
}
896+
```
897+
898+
And here we write a generator function that will return our data:
899+
900+
```javascript
901+
function* getData() {
902+
var entry1 = yield request('http://some_api/item1');
903+
var data1 = JSON.parse(entry1);
904+
var entry2 = yield request('http://some_api/item2');
905+
var data2 = JSON.parse(entry2);
906+
}
907+
```
908+
909+
By the power of `yield`, we are gauranteed that `entry1` will have the data needed to be parsed and stored
910+
in `data1`.
911+
912+
While generators allow us to write asynchronous code in a synchronous manner, there is no clear
913+
and easy path for error propagation. As such, as we can augment our generator with Promises:
914+
915+
```javascript
916+
function request(url) {
917+
return new Promise((resolve, reject) => {
918+
getJSON(url, resolve);
919+
});
920+
}
921+
```
922+
923+
And we write a function which will step through our generator using `next` which in turn will utilize our
924+
`request` method above to yield a Promise:
925+
926+
```javascript
927+
function iterateGenerator(gen) {
928+
var generator = gen();
929+
var ret;
930+
(function iterate(val) {
931+
ret = generator.next();
932+
if(!ret.done) {
933+
ret.value.then(iterate);
934+
}
935+
})();
936+
}
937+
```
938+
939+
<sup>[(回到目录)](#table-of-contents)</sup>
940+
941+
By augmenting our Generator with Promises, we have a clear way of propogating errors through the use of our
942+
Promise `.catch` and `reject`. To use our newly augmented Generator, it is as simple as before:
943+
944+
```javascript
945+
iterateGenerator(function* getData() {
946+
var entry1 = yield request('http://some_api/item1');
947+
var data1 = JSON.parse(entry1);
948+
var entry2 = yield request('http://some_api/item2');
949+
var data2 = JSON.parse(entry2);
950+
});
951+
```
952+
953+
We were able to reuse our implementation to use our Generator as before, which shows their power. While Generators
954+
and Promises allow us to write asynchronous code in a synchronous manner while retaining the ability to propogate
955+
errors in a nice way, we can actually begin to utilize a simpler construction that provides the same benefits:
956+
[async-await](https://github.com/DrkSephy/es6-cheatsheet#async-await).
957+
958+
<sup>[(回到目录)](#table-of-contents)</sup>
959+
960+
## Async Await
961+
962+
While this is actually an upcoming ES2016 feature, `async await` allows us to perform the same thing we accomplished
963+
using Generators and Promises with less effort:
964+
965+
```javascript
966+
var request = require('request');
967+
968+
function getJSON(url) {
969+
return new Promise(function(resolve, reject) {
970+
request(url, function(error, response, body) {
971+
resolve(body);
972+
});
973+
});
974+
}
975+
976+
async function main() {
977+
var data = await getJSON();
978+
console.log(data); // NOT undefined!
979+
}
980+
981+
main();
982+
```
983+
984+
Under the hood, it performs similarly to Generators. I highly recommend using them over Generators + Promises. A great resource
985+
for getting up and running with ES7 and Babel can be found [here](http://masnun.com/2015/11/11/using-es7-asyncawait-today-with-babel.html).
986+
987+
<sup>[(回到目录)](#table-of-contents)</sup>

0 commit comments

Comments
 (0)