手动封装Promise之同步代码

在封装之前,我需要给大家提及一下Promise的原理,因为Promise原理是在面试过程中常考的内容,需要大家认真理解并掌握。

1. Promise原理:

首先Promise有三种状态,分别是pending、resolved(也可以叫fulfilled)、rejected。pending表示Promise对象实例创建的时候初始状态;resolved(fulfilled)可以理解为成功的状态;rejected可以理解为失败的状态。
构造一个Promise实例需要给Promise构造函数传入一个函数,然后传入的函数需要有两个形参,两个参数都是函数类型的参数,分别是resolved和rejected。
Promise上还有then方法,then方法就是用来指定Promise对象的状态改变时需要执行的操作。当状态变为resolved时需执行第一个函数onResolved;当状态变为rejected时需执行第二个函数onRejected。
在这里我们需要注意:pending状态只能变成resolved(fulfilled)成功状态或者pendin状态只能变成失败rejected状态这两种状态;不能resolved(fulfilled)成功状态变成pending状态或者失败状态变成pending状态或者resolved(fulfilled)成功状态和rejected失败状态之间各自相互转换。

2. 手动封装Promise同步代码

在理解完上面的Promise原理之后,接下来我就带大家去封装一个同步的代码,在下一次的分享中我会接着带大家去封装一个Promise异步的代码。

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// Promise同步代码
// 定义一个MyPromise的构造函数
function MyPromise(fn){
// 初始化
let _this = this;
_this.status = 'pending';
_this.value = undefined;
// 定义resolved函数
function resolved(val){
_this.status = 'resolved';
_this.value = val;
}
// 定义rejected函数
function rejected(err){
_this.status = 'rejected';
_this.value = err;
}
// 自执行以下fn函数,因此才需要定义一个_this
fn(resolved,rejected);
}
// 在MyPromise构造函数的原型上定义一个then方法
MyPromise.prototype.then = function(onResolved,onRejected){
let newPromise;
let _this = this;
// 注意:如果不写下面两行代码的判断,那么在穿透时就会报错
// 举一个例子:let p = new MyPromise((resolved,rejected)=>{
// resolved('hi');
// });
// let p1 = p.then().then((data)=>{}); //报错
// 报错信息为: onRejected is not a function
onResolved = typeof onResolved === 'function' ? onResolved : function(value){return value;};
onRejected = typeof onRejected === 'function' ? onRejected : function(err){return err;};

if(_this.status === 'resolved'){
return (newPromise = new MyPromise(function(resolved,rejected){
let result = onResolved(_this.value);
if(result instanceof MyPromise){
result.then(resolved,rejected);
}else{
resolved(result);
}
}));
}
if(_this.status === 'rejected'){
return (newPromise = new MyPromise(function(resolved,rejected){
let result = onRejected(_this.value);
if(result instanceof MyPromise){
result.then(resolved,rejected);
}else{
resolved(result);
}
}));
}
};

let p = new MyPromise(function(resolved,rejected){
resolved('hello');
});
console.log(p); // MyPromise {status: "resolved", value: "hello"}
let p1 = p.then((data)=>{
return new MyPromise(function(resolved,rejected){
rejected(new Error('Oh,I am Error!!!'));
});
});
console.log(p1); // MyPromise {status: "rejected", value: Error: Oh,I am Error!!!}
let p2 = p1.then(function(data){
return 'data:' + data;
},function(err){
return 'err:' + err;
});
console.log(p2); // MyPromise {status: "resolved", value: "err:Error: Oh,I am Error!!!"}
let p3 = p.then().then(function(data){});
console.log(p3); // MyPromise {status: "resolved", value: undefined}