Skip to content

Commit b68f399

Browse files
committed
开始前面两章
1 parent 8096cec commit b68f399

8 files changed

+115
-10
lines changed

01-issues-of-async.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
异步的问题
2+
========
3+
4+
故事必须从头说起,在很久很久以前……
5+
6+
## 为校验表单,JavaScript 诞生了
7+
8+
在那个拨号上网的洪荒年代,浏览器还非常初级,与服务器进行数据交互的唯一方式就是提交表单。用户填写完成之后,交给服务器处理,如果内容合规当然好,如果不合规就麻烦了,必须打回来重填。那会儿网速还是论 Kb 的,比如我刚上网那会儿开始升级到 33.6Kb,主流还是 22.4Kb……
9+
10+
所以很容易想象:当用户填完100+选项,按下提交按钮,等待几十秒甚至几分钟之后,反馈回来的信息却是:“您的用户名不能包含大写”,他会有多么的崩溃多么的想杀人。为了提升用户体验,网景公司的[布兰登·艾克](https://zh.wikipedia.org/wiki/%E5%B8%83%E8%98%AD%E7%99%BB%C2%B7%E8%89%BE%E5%85%8B)大约用10天时间,开发出 JavaScript 的原型,从此,这门注定改变世界的语言就诞生了。
11+
12+
只是当时大家都还不知道,发明它的目的,只是为校验表单。
13+
14+
## JavaScript 中存在大量异步计算
15+
16+
同样为了提升用户体验,HTML DOM 也选择了边加载,边生成,边渲染的策略。再加上要等待用户操作,大量交互都以事件来驱动。于是,JavaScript 就存在大量的异步计算。
17+
18+
这也带来一个好处,作为一门 UI 语言,异步操作帮 JavaScript 避免了页面冻结。
19+
20+
为什么异步操作可以避免界面冻结呢?
21+
22+
### 同步的利弊
23+
24+
> 假设你去到一家饭店,自己找座坐下了,然后招呼服务员拿菜单来。
25+
26+
> 服务员说:“对不起,我是‘同步’服务员,我要服务完这张桌子才能招呼你。”
27+
28+
> 那一桌人明明已经吃上了,你只是想要菜单,这么小的一个动作,服务员却要你等待别人的一个大动作完成。你是不是很想抽ta?
29+
30+
这就是“同步”的问题:顺序交付的工作1234,必须按照1234的顺序完成。
31+
32+
不过它的也有好处:逻辑非常简单。你不用担心每步操作会消耗多少时间,反正每步操作都会在上一步完成之后才进行,只管往后写就是了。
33+
34+
### 异步的利弊
35+
36+
与之相反,异步,则是将耗时很长的 A 交付的工作交给系统之后,就去继续做 B 交付的工作。等到系统完成之后,再通过回调或者事件,继续做 A 剩下的工作。
37+
38+
从观察者的角度,看起来 AB 工作的完成顺序,和交付他们的时间顺序无关,所以叫"异步"。
39+
40+
所以,那些需要大量计算(比如 Service Worker),或者复杂查询(比如 Ajax)的工作,JS 引擎把它们交给系统之后,就回来继续待机了,于是我们总能看到浏览器第一时间响应我们的操作,感觉非常好。
41+
42+
有利必有弊,异步的缺点就是:必须通过特殊的语法才能实现,而这些语法看起来就不如同步那样清晰明确了。
43+
44+
## 异步计算的实现
File renamed without changes.

04-2-xiaochengxu.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ new Promise( (resolve, reject) => {
6767
});
6868
```
6969

70-
## Await/Async
70+
## Async Functions
7171

72-
“微信 Web 开发者工具”里面集成了 Babel 转译工具,可以将 ES6 编译成 ES5,不过 Await/Async 就不支持了。此时我们可以选择自行编译,或者只使用 Promise。
72+
“微信 Web 开发者工具”里面集成了 Babel 转译工具,可以将 ES6 编译成 ES5,不过 Async Functions 就不支持了。此时我们可以选择自行编译,或者只使用 Promise。
7373

7474
自行编译时,请注意,小程序页面没有 `<script>`,只能引用同名 `.js`,所以要留神输出的文件名。这里建议把 JS 写在另一个文件夹,然后用 Babel 转译,把最终文件写过来。
7575

04-3-other.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,30 @@
11
其它场景
2-
========
2+
========
3+
4+
现在越来越多的库与框架都开始返回 Promise 对象,这里暂列一二。
5+
6+
## Fetch API
7+
8+
Fetch API 是 XMLHttpRequest 的现代化替代方案,它更强大,也更友好。它直接返回一个 Promise 实例,并分两步返回结果。
9+
10+
第一次返回的 `response` 包含了请求的状态,接下来可以调用 `response.json()` 生成新的 Promise 对象,它会在加载完成后返回结果。
11+
12+
```javascript
13+
fetch('some.json')
14+
.then( response => {
15+
if (response.ok) {
16+
return response.json();
17+
}
18+
throw new Error(response.statusText);
19+
})
20+
.then( json => {
21+
// do something with the json
22+
})
23+
.catch( err => {
24+
console.log(err);
25+
});
26+
```
27+
28+
除了 `response.json()` 之外,它还有 `.blob()``.text()` 等方法,具体可以参考 [MDN 上的文档](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
29+
30+
它的浏览器覆盖率请看[这里](http://caniuse.com/#search=fetch),值得注意的是,iOS 10.2 还不支持,所以现在必须提供兼容方案。

04-lets-do-it.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
1. 可读性更好
1111
2. 返回的结果可以加入任何 Promise 队列
12-
3. 可以使用 Await/Async
12+
3. 可以使用 Async Functions
1313

1414
我们就拿读取文件来举个例子。
1515

@@ -86,7 +86,7 @@ doSomething()
8686
// 继续处理
8787
});
8888

89-
// async/await
89+
// async functions
9090
await doSomething();
9191
if (await openConfirmPopup('确定么')) {
9292
// 继续处理
@@ -124,9 +124,9 @@ stat('.')
124124
1. 最后一个参数是回调函数
125125
2. 回调函数的参数为 `(err, result)`,前面是可能的错误,后面是正常的结果
126126

127-
### 结合 Await/Async 使用
127+
### 结合 Async Functions 使用
128128

129-
同样是上面的例子,如果想要结合 Await/Async,可以这样使用:
129+
同样是上面的例子,如果想要结合 Async Functions,可以这样使用:
130130

131131
```javascript
132132
const util = require('util');

10-review.md

+32
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,38 @@
11
回顾
22
========
33

4+
## Pormise
5+
6+
相较于传统的回调模式,Promise 有着巨大的进步,值得我们学习和使用。
7+
8+
### 优势
9+
10+
1. 可以很好地解决异步回调不好写、不好读的问题
11+
2. 可以使用队列,并且在对象之间传递
12+
3. 不引入新语言元素,大部分浏览器已经原生支持,可以放心使用;个别不支持的,也有完善的解决方案
13+
14+
### 不足
15+
16+
1. 引入了不少新概念、新写法,学习成本不低
17+
2. 也会有嵌套,可能看起来还很复杂
18+
3. 没有真正解决 `return/try/catch` 的问题
19+
20+
## Async Functions
21+
22+
异步函数是 ES2017 里非常有价值的新特性,可以极大的改善异步开发的环境。
23+
24+
除了覆盖率,几乎找不出什么黑点。
25+
26+
目前大部分主流浏览器都已经实现对它的支持,除了 IE 和 iOS 10.2。我们可以针对这两个系列的浏览器里进行降级,不过请注意,因为 Async Functions 引入了新的语法元素,所以必须用 Babel 编译的方式来处理。
27+
28+
## 一些小 Tips
29+
30+
这是我犯过的一些错误,希望成为大家前车之鉴。
31+
32+
* `.resolve()` `.reject()` 不会自动 `return`
33+
* Promise 里必须 `.resolve()` `.reject()` `throw err` 才会改变状态,`.then()` 不需要。
34+
* `.resolve()` 只会返回一个值,返回多个值请用数组或对象。
35+
436
## 参考阅读
537

638
* [让微信小程序支持 ES6 的 Promise 特性](https://haojen.github.io/2016/11/23/wechat-app-promise/)

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
* ES6 = ES2015
2323
* ES7 = ES2016 + ES2017
24+
* 异步函数 = Async Functions = Await/Async
2425

2526
范例代码中会使用 ES6 的一些语法,也会混用 ES6 Modules/CommonJS,请大家不要见怪。
2627

SUMMARY.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
# Summary
22

3-
* [前言](00-README.md)
3+
* [前言](README.md)
44
* [异步的问题](01-issues-of-async.md)
55
* [Promise 方案](02-promise-intro.md)
66
* [Promise 入门](02-1-promise-basic.md)
77
* [Promise 进阶](02-2-promise-advanced.md)
8-
* [Await/Async 方案](03-await-async.md)
9-
* [Await/Async 和 Promise 队列的异同](03-1-difference-between-await-async-and-promise.md)
8+
* [Async Functions 方案](03-await-async.md)
9+
* [Async Functions 和 Promise 的异同](03-1-difference-between-await-async-and-promise.md)
1010
* [一起实战吧](04-lets-do-it.md)
1111
* [降级](04-1-downgrade.md)
1212
* [小程序](04-2-xiaochengxu.md)

0 commit comments

Comments
 (0)