Skip to content

Commit b5b322c

Browse files
committed
working on promise
1 parent 6d836af commit b5b322c

File tree

2 files changed

+133
-3
lines changed

2 files changed

+133
-3
lines changed

Diff for: 02-1-promise-basic.md

+132-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,132 @@
1-
Promise 入门
2-
========
1+
Promise 详解
2+
========
3+
4+
我们先来看 Promise 的用法。
5+
6+
```javascript
7+
new Promise(
8+
/* 执行器 executor */
9+
function (resolve, reject) {
10+
// 一段耗时很长的异步操作
11+
12+
resolve(); // 数据处理完成
13+
14+
reject(); // 数据处理出错
15+
}
16+
)
17+
.then(function A() {
18+
// 成功,下一步
19+
}, function B() {
20+
// 失败,做相应处理
21+
});
22+
```
23+
24+
Promise 是一个**代理对象**,它和原先的异步操作并无关系。它接受一个“执行器 executor”作为参数,我们要把原先要执行的异步(并非一定要异步,以后会说明,这里你可以先不深究)操作放进去。
25+
26+
执行器在 Promise 实例创建后立刻开始执行。执行器自带两个参数:`resolve``reject`,这二位都是函数,执行它们会改变 Promise 实例的状态。
27+
28+
Promise 实例有三个状态:
29+
30+
1. `pending` [待定] 初始状态,新创建的实例处于这个状态
31+
2. `fulfilled` [实现] 操作成功,在执行器里调用 `resolve()` 之后,实例切换到这个状态
32+
3. `rejected` [被否决] 操作失败,在执行器里调用 `reject()` 之后,实例切换到这个状态
33+
34+
Promise 实例状态改变之后,就会触发后面对应的 `.then()` 参数里的函数,继续执行后续步骤。另外,Promise 的实例状态只会改变一次,确定为 `fulfilled``rejected` 之一后就不会再变。
35+
36+
## 一个简单的例子
37+
38+
```javascript
39+
new Promise( resolve => {
40+
setTimeout( () => {
41+
resolve('hello');
42+
}, 2000);
43+
})
44+
.then( value => {
45+
console.log( value + ' world');
46+
});
47+
48+
// 输出:
49+
// hello world
50+
```
51+
52+
这是最简单的一种情况。执行器里面是一个定时器,2秒种之后,它会执行 `resolve('hello')`,将 Promise 实例的状态置为 `fulfilled`。接下来 `.then()` 里面的函数就会被触发,它接受前面 Promise 返回的值 `'hello'`,将其与 `' world'` 连接起来,输出“hello world”。
53+
54+
## 再来一个稍复杂的例子
55+
56+
```javascript
57+
new Promise( resolve => {
58+
setTimeout( () => {
59+
resolve('hello');
60+
}, 2000);
61+
})
62+
.then( value => {
63+
return new Promise( resolve => {
64+
setTimeout( () => {
65+
resolve('world')
66+
}, 2000);
67+
});
68+
})
69+
.then( value => {
70+
console.log( value + ' world');
71+
});
72+
73+
// 输出:
74+
// world world
75+
```
76+
77+
这个例子与上一个例子的不同之处在于,我在 `.then()` 的后面又跟了一个 `.then()`。并且在第一个 `.then()` 里又返回了一个 Promise 实例。于是,第二个 `.then()` 就又等了2秒才执行,并且接收到的参数是第一个 `.then()` 返回的 Promise 返回的 `'world'`(好拗口),而不是起始 Promise 返回的 `'hello'`
78+
79+
这就必须说明 Promise 里 `.then()` 的定义。
80+
81+
## `.then()`
82+
83+
`.then()` 其实接受两个函数作为参数,分别代表 `fulfilled` 状态时的处理函数和 `rejected` 状态时的处理函数。只不过通常情况下,我会建议大家使用 `.catch()` 捕获 `rejected` 状态。这个后面还会说到,所以暂时按下不表。
84+
85+
`.then()` 会返回一个新的 Promise 实例,所以它可以链式调用,如前面的例子所示。当前面的 Promise 状态改变时,`.then()` 会执行特定的状态响应函数,并将其结果,调用自己的 Promise 的 `resolve()` 返回。
86+
87+
### Promise.resolve()
88+
89+
这里必须补充一下 Promise.resolve() 的相关知识。它是 Promise 的静态方法,可以返回一个状态为 `fulfilled` 的 Promise 实例。
90+
91+
它可以接受四种不同类型的参数,并且返回不同的值:
92+
93+
1. 参数为空,返回一个 `fulfilled` 实例,响应函数的参数也为空
94+
2. 参数不为空、也不是 Promise 实例,返回 `fulfilled` 实例,只不过响应函数能得到这个参数
95+
3. 参数为 Promise 实例,直接原样返回
96+
4. 参数为 thenable 对象,里可以执行它的 `.then()`
97+
98+
用一段代码来示范吧,比较简单,就不一一解释了。
99+
100+
```javascript
101+
Promise.resolve()
102+
.then( () => {
103+
console.log('Step 1');
104+
return Promise.resolve('Hello');
105+
})
106+
.then( value => {
107+
console.log(value, 'World');
108+
return Promise.resolve(new Promise( resolve => {
109+
setTimeout(() => {
110+
resolve('Good');
111+
}, 2000);
112+
}));
113+
})
114+
.then( value => {
115+
console.log(value, ' evening');
116+
return Promise.resolve({
117+
then() {
118+
console.log(', everyone');
119+
}
120+
})
121+
});
122+
123+
// 输出:
124+
// Step 1
125+
// Hello World
126+
// (2秒之后) Good evening
127+
// , everyone
128+
```
129+
130+
### 继续 `.then()` 的话题
131+
132+
结合上一小节关于 Promise.resolve() 的讲解,我们应该可以推断出 `.then()` 里的状态响应函数不同返回结果对进程的影响了吧。

Diff for: SUMMARY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* [异步的问题](01-2-issue.md)
77
* [异步的发展](01-3-growing.md)
88
* [Promise 方案](02-promise-intro.md)
9-
* [Promise 入门](02-1-promise-basic.md)
9+
* [Promise 详解](02-1-promise-basic.md)
1010
* [Promise 进阶](02-2-promise-advanced.md)
1111
* [Async Functions 方案](03-await-async.md)
1212
* [Async Functions 和 Promise 的异同](03-1-difference-between-await-async-and-promise.md)

0 commit comments

Comments
 (0)