全面解析Promise
AlexChiang 2020-02-16
JavaScript
ES6
ruanyif ES6 入门 + 掘金文章 总结
# 三种状态
- 等待中 pending
- 完成 fulfilled
- 拒绝 rejected
立即执行性: 创建 Promise 实例时 作为参数传入的函数会被 立即执行
var p1 = new Promise(function(resolve, reject) {
// 同步代码 -> 实例创建完成时状态已变为resolved
resolve(1);
});
var p2 = new Promise(function(resolve, reject) {
// 异步代码
setTimeout(function() {
resolve(2); // 500ms后才执行此步
}, 500);
});
var p3 = new Promise(function(resolve, reject) {
// 异步代码
setTimeout(function() {
reject(3); // 500ms后才执行此步
}, 500);
});
// 顺序执行部分
console.log(p1); // resolved状态
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 1}
console.log(p2); // pending状态
console.log(p3); // pending状态
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
setTimeout(function() {
console.log(p2);
}, 1000);
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 2}
setTimeout(function() {
console.log(p3);
}, 1000);
// Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: 3}
// 注册回调函数
p1.then(function(value) {
console.log(value);
});
p2.then(function(value) {
console.log(value);
});
p3.catch(function(err) {
console.log(err);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 工作原理
- 生成实例
- 指定回调
// 创建一个promise实例 构造函数接收一个函数作为参数
var p1 = new Promise(Fn);
// 该函数 有两个函数作为参数
function Fn(resolve, reject) {
// 函数内部会定义什么时候让状态变成resolve或reject
if (异步操作成功) {
resolve(value);
} else {
reject(value);
}
}
// 以上便是实例生成
// 至此还未告知成功后做什么
// 实例生成后用then方法指定resolved状态和rejeceted状态的回调函数
p1.then(
val => {
// 成功后做什么
},
err => {
// 失败后做什么
}
);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
如果后续任务是异步任务,必须 return 一个新的 promise 对象
var p = new Promise(function(resolve, reject) {
resolve(1);
});
p.then(function(value) {
//第一个then
//value = 1
console.log(value);
return value * 2;
})
.then(function(value) {
//第二个then
//value = 1 * 2
console.log(value);
})
.then(function(value) {
//第三个then
// 无value值
console.log(value);
return Promise.resolve("resolve");
})
.then(function(value) {
//第四个then
//value = 'resolve'
console.log(value);
return Promise.reject("reject");
})
.then(
//第五个then
function(value) {
console.log("resolve: " + value);
},
// 只执行reject err='reject'
function(err) {
console.log("reject: " + err);
}
);
// 1
// 2
// undefined
// "resolve"
// "reject: reject"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# API
# .then()
- 回调异步性:
Promise 接收的函数参数是同步执行的,但 then 方法中的回调函数执行则是异步的,因此,"success"会在后面输出。
var p = new Promise(function(resolve, reject) {
resolve("success");
});
p.then(function(value) {
console.log(value);
});
console.log("which one is called first ?");
// "which one is called first ?"
// "success"
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# .resolve()
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(p1);
var p3 = new Promise(function(resolve, reject) {
resolve(1);
});
var p4 = new Promise(function(resolve, reject) {
resolve(p1);
});
console.log(p1 === p2); // true
console.log(p1 === p3); // false
// 通过new方法创建的是一个新的对象
console.log(p1 === p4); // false
console.log(p3 === p4); // false
p4.then(function(value) {
console.log("p4=" + value);
});
p2.then(function(value) {
console.log("p2=" + value);
});
p1.then(function(value) {
console.log("p1=" + value);
});
// p2=1
// p1=1
// p4=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
为什么 p4 最后输出?当 resolve 接收参数是 promise 对象时需要进行拆箱
# .resolve
vs.reject
var p1 = new Promise(function(resolve, reject) {
resolve(Promise.resolve("resolve"));
});
var p2 = new Promise(function(resolve, reject) {
resolve(Promise.reject("reject"));
});
var p3 = new Promise(function(resolve, reject) {
reject(Promise.resolve("resolve"));
});
p1.then(
function fulfilled(value) {
console.log("fulfilled: " + value);
},
function rejected(err) {
console.log("rejected: " + err);
}
);
p2.then(
function fulfilled(value) {
console.log("fulfilled: " + value);
},
function rejected(err) {
console.log("rejected: " + err);
}
);
p3.then(
function fulfilled(value) {
console.log("fulfilled: " + value);
},
function rejected(err) {
console.log("rejected: " + err);
}
);
// p3 rejected: [object Promise]
// p1 fulfilled: resolve
// p2 rejected: reject
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- 先输出 p3:then 中的 reject 不具备拆箱功能 无需等待即输出
[object Promise]
- p1,p2 中 resolve 正常进行异步的拆箱 然后执行 console.log