文章目录
  1. 1. 执行顺序
  2. 2. 值的穿透
  3. 3. then的问题
  4. 4. 注意
  5. 5. 手写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
// 三个状态 resolved(解决) rejected(拒绝) pending(等待)
// promise中放了一个函数 函数executor 执行器
// resolve和reject都是函数 调用后可以让状态进行改变

// promise解决的问题有
//1) 回调地狱
//2)解决 并发异步,再同一时刻内获取并发的结果
//3) 链式调用 (jquery)

//常用写法
let promise=new Promise((resolve,reject)=>{
setTimeout(()=>{ //这个定时器就相当于我们的异步代码 (比如ajax)
resolve('123')
})

})
promise.then(res=>{
console.log(res) //123
},err=>{

})
//链式调用 说明then返回的是一个Promise的实例
promise.then(res=>{
console.log(res)
},err=>{

}).then(res=>{
console.log(res)
},err=>{

})

执行顺序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//执行顺序
let promise=new Promise((resolve,reject)=>{

resolve('123')
console.log(1)

})
promise.then(res=>{
console.log(res) //123
},err=>{

})
//打印顺序 1,123
//默认promise中的executor(就是Promise中的参数)是同步执行的 //而then中的参数相当于回调

值的穿透

1
2
3
4
5
6
//值的穿透 then不传参数就默认走到下一then中
promise.then().then(res=>{
console.log(res) //123
},err=>{

})

then的问题

1
2
3
4
5
6
7
8
9
10
11
//then的问题
// 最常见的 如果返回的是普通值 直接把值作为外层下一次then的参数
promise.then(res=>{
return 1 //返回除了Promise外的参数 直接把值作为外层下一次then的参数
},err=>{

}).then(res=>{
console.log(res) //1
},err=>{

})

注意

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// then方法调用后,返回的是一个新的promise  //会把这个promise下的所有包括当前返回的promise执行完毕  取到成功或失败的结果
//当做外层下一次then的成功或失败的结果 执行过程中失败就直接取失败 //成功就一直执行 知道完后拿到结果
promise.then((data) => {
return new Promise((resolve,reject)=>{
resolve(new Promise((resolve,reject)=>{
resolve('123456');
}))
})
}, err => {
console.log( err);
}).then(res=>{
console.log(res) //123456
},err=>{

})

手写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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
class Promise {
constructor(executor) {
// 默认状态是等待态
this.status = 'pending';
//成功后的值
this.value = undefined;
//失败的原因
this.reason = undefined;
// 存放成功的回调 解决异步调用 就是我们常用的写法那种
this.onResolvedCallbacks = [];
// 存放失败的回调 用成功就有失败
this.onRejectedCallbacks = [];
//resolve,reject 我们executor中的参数
let resolve = (data) => {
//当resolve调用时相当于成功 所以改变状态为成功 reject同理
if (this.status === 'pending') {
this.value = data;
this.status = 'resolved';
this.onResolvedCallbacks.forEach(fn => fn());
}
}
let reject = (reason) => {
if (this.status === 'pending') {
this.reason = reason;
this.status = 'rejected';
this.onRejectedCallbacks.forEach(fn => fn());
}
}

try { // 执行时可能会发生异常
executor(resolve, reject);
} catch (e) {
reject(e); // promise失败了
}
}
//then 也有两个参数 成功的回调 和失败的回调
then(onFulFilled, onRejected) {
// 解决onFulFilled,onRejected没有传的问题 值的穿透
onFulFilled = typeof onFulFilled === 'function' ? onFulFilled : y => y;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };

let promise2; //then的返回值
if (this.status === 'resolved') {
promise2 = new Promise((resolve, reject) => {
// 成功的逻辑 失败的逻辑
setTimeout(() => {//模拟Promise执行顺序
try {
let x = onFulFilled(this.value);
// 看x是不是promise 如果是promise 取他的结果 作为promise2,成功的结果
// 如果要是返回一个普通值 作为promise2,成功的结果

// resolvePromise可以解析x和promise2之间的关系
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
}
if (this.status === 'rejected') {
promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0);
});
}
// 当前既没有完成 也没有失败
if (this.status === 'pending') {
// 存放成功的回调
promise2 = new Promise((resolve, reject) => {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulFilled(this.value);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
}, 0)
});
// 存放失败的回调
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
});
})
}
return promise2; // 调用then后返回一个新的promise
}
}
function resolvePromise(promise2, x, resolve, reject) {
// 判断x是不是promise2
// [规范]里规定了一段代码,这个代码可以实现我们的promise和别人的promise可以进行交互
if (promise2 === x) { // 不能自己等待自己完成
return reject(new TypeError('循环引用'));
}
// x不是null或者是对象或者函数
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let called; // 防止成功后调用失败
try { // 防止取then是出现异常 Object.defineProperty
let then = x.then; // 取x的then方法 {then:{}}
if (typeof then === 'function') { // 如果then是函数我就认为它是promise
// call 第一个参数是this ,后面的是成功的回调和失败的回调
then.call(x, y => { // 如果y是promise就继续递归解析promise
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => { // 只要失败了就失败了
if (called) return;
called = true;
reject(r);
});
} else { // then是一个普通对象,就直接成功即可1
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else { // x = 123
resolve(x); // x就是一个普通值
}
}
// promise的语法糖,测试
Promise.deferred = Promise.defer = function () {
let dfd = {};
dfd.promise = new Promise((resolve,reject)=>{
dfd.resolve = resolve;
dfd.reject = reject;
})
return dfd;
}
// npm install promises-aplus-tests -g
// promises-aplus-tests 文件名
module.exports = Promise;
// 写完promise会测试一下
文章目录
  1. 1. 执行顺序
  2. 2. 值的穿透
  3. 3. then的问题
  4. 4. 注意
  5. 5. 手写promise