搭建基本结构
项目文件结构
1
2
3
4
5
6
|
.
└── custom
├── main.js
├── package.json
└── src
└── promise.js
|
promise.js
1
2
3
4
5
6
7
|
export function Promise(executor) {
}
Promise.prototype.then = function (onResolved, onRejected) {
}
|
main.js
1
2
3
4
5
6
7
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
})
p.then(value => console.log(value), reason => console.log(reason))
|
package.json
1
2
3
4
5
6
7
8
9
10
11
12
|
{
"name": "custom",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"type": "module"
}
|
初步实现 resolve 和 reject
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
}
function reject(data) {
self.PromiseState = 'rejected'
self.PromiseResult = data
}
// 同步调用执行器
executor(resolve, reject)
}
Promise.prototype.then = function (onResolved, onRejected) {
}
|
处理执行器执行产生的异常
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
}
function reject(data) {
self.PromiseState = 'rejected'
self.PromiseResult = data
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
}
|
main.js
1
2
3
4
5
6
7
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
throw 'error'
})
p.then(value => console.log(value), reason => console.log(reason))
|
限制状态只能修改一次
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
}
|
同步执行单个回调
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
}
if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
})
p.then(value => {
console.log('success, msg: ', value)
}, reason => {
console.log('error, msg: ', reason)
})
|
异步执行单个回调
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callback = {}
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
if (self.callback.onResolved) {
self.callback.onResolved(data)
}
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
if (self.callback.onRejected) {
self.callback.onRejected(data)
}
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
}
else if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
}
else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callback = {
onResolved: onResolved,
onRejected: onRejected
}
}
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('success')
resolve('OK')
}, 1000)
})
p.then(value => {
console.log('success, msg: ', value)
}, reason => {
console.log('error, msg: ', reason)
})
|
异步执行多个回调
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (this.PromiseState === 'fulfilled') {
onResolved(this.PromiseResult)
} else if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('success')
resolve('OK')
}, 1000)
})
p.then(value => {
console.log('success, msg: ', value)
}, reason => {
console.log('error, msg: ', reason)
})
p.then(value => {
console.log('success2, msg: ', value)
}, reason => {
console.log('error, msg: ', reason)
})
|
同步状态下 then 方法返回 Promise 对象
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
} else if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: onResolved,
onRejected: onRejected
})
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
})
let result = p.then(value => {
return new Promise((resolve, reject) => {
resolve('success in new Promise')
})
}, reason => {
console.log('error, msg: ', reason)
}).then(value => {
console.log(value)
})
console.dir(result)
|
异步状态下 then 方法返回 Promise 对象
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
} else if (this.PromiseState === 'rejected') {
onRejected(this.PromiseResult)
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
try {
let result = onResolved(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
},
onRejected: function () {
try {
let result = onRejected(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
})
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000)
})
let result = p.then(value => {
throw 'ERROR-1'
}, reason => {
console.log('LEVEL1-ERROR')
})
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
|
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
timer: Promise {
PromiseState: 'rejected',
PromiseResult: 'ERROR-1',
callbacks: []
}
|
处理执行 then 方法前 Promise 状态变为 rejected 的情况
修改前
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
// setTimeout(() => {
reject('ERROR')
// }, 1000)
})
let result = p.then(value => {
throw 'ERROR-1'
}, reason => {
console.log('LEVEL1-ERROR')
}).then(value => {
console.log('aa')
}, reason => {
console.log('bb')
})
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
|
LEVEL1-ERROR
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
timer: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
|
从上面代码的执行结果可以看出,此时没有输出 aa 也没有输出 bb。主要原因是当 then 方法执行前 Promise 的状态变为 rejected,此时执行 this.PromiseState === 'rejcted'
里面的代码,但是这些代码没有改变返回的新 Promise 实例的状态,导致被存在新 Promise 实例中的回调函数(输出 aa 的成功回调和输出 bb 的失败回调)一直没有被执行。
修改后
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
try {
let result = onResolved(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
} else if (this.PromiseState === 'rejected') {
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
try {
let result = onResolved(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
},
onRejected: function () {
try {
let result = onRejected(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
})
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
// setTimeout(() => {
reject('ERROR')
// }, 1000)
})
let result = p.then(value => {
throw 'ERROR-1'
}, reason => {
console.log('LEVEL1-ERROR')
}).then(value => {
console.log('aa')
}, reason => {
console.log('bb')
})
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
7
8
9
10
11
12
|
LEVEL1-ERROR
aa
immediate: Promise {
PromiseState: 'fulfilled',
PromiseResult: undefined,
callbacks: []
}
timer: Promise {
PromiseState: 'fulfilled',
PromiseResult: undefined,
callbacks: []
}
|
代码重构
优化前
then 方法中多次使用到类似如下的代码,只有一处调用的函数不同(下面的代码中调用的是 onRejected),将该代码封装到一个单独的函数,有利于后期维护、增加可读性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
try {
let result = onRejected(this.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
|
优化后
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
const self = this
return new Promise((resolve, reject) => {
function handler(callback) {
try {
let result = callback(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
handler(onResolved)
} else if (this.PromiseState === 'rejected') {
handler(onRejected)
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
handler(onResolved)
},
onRejected: function () {
handler(onRejected)
}
})
}
})
}
|
main.js
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
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000)
})
let result = p.then(() => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('ERROR')
})
}, 1000)
}, () => {
}).then(() => {
console.log('SUCCESS')
}, () => {
console.log('FAILED')
})
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
7
|
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
FAILED
timer: Promise {
PromiseState: 'fulfilled',
PromiseResult: undefined,
callbacks: []
}
|
catch 方法、异常穿透、值传递
promise.js
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
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 执行成功的回调
self.callbacks.forEach(item => item.onResolved(data))
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 执行失败的回调
self.callbacks.forEach(item => item.onRejected(data))
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (typeof onResolved !== 'function') {
// 实现值传递的关键步骤
onResolved = value => value
}
if (typeof onRejected !== 'function') {
// error: 由于 throw reason 没有返回值,故不能省略大括号
// onRejected = reason => throw reason
// 实现异常穿透的关键步骤
onRejected = reason => {
throw reason
}
}
const self = this
return new Promise((resolve, reject) => {
function handler(callback) {
try {
let result = callback(self.PromiseResult)
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
handler(onResolved)
} else if (this.PromiseState === 'rejected') {
handler(onRejected)
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
handler(onResolved)
},
onRejected: function () {
handler(onRejected)
}
})
}
})
}
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
|
main.js
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
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
setTimeout(() => {
// resolve('OK')
reject('ERROR')
}, 1000)
})
let result = p.then(() => console.log(1))
.then(() => console.log(2))
.then(() => console.log(3))
.catch(reason => {
console.log(reason) // 异常穿透
})
.then(() => 23) // 值传递
.then()
.then(value => {
console.log(value)
})
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
7
8
|
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
ERROR
23
timer: Promise {
PromiseState: 'fulfilled',
PromiseResult: undefined,
callbacks: []
}
|
实现 Promise.resolve()
在 promise.js 中添加如下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
v => {
resolve(v)
},
r => {
reject(r)
})
} else {
resolve(value)
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
|
import {Promise} from "./src/promise.js";
let result = Promise.resolve(new Promise((resolve, reject) => {
setTimeout(() => {
reject('ERROR')
}, 1000)
}))
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
|
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
timer: Promise {
PromiseState: 'rejected',
PromiseResult: 'ERROR',
callbacks: []
}
|
实现 Promise.reject()
在 promise.js 中添加如下代码
1
2
3
4
5
|
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
|
import {Promise} from "./src/promise.js";
let result = Promise.reject(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK')
}, 1000)
}))
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
immediate: Promise {
PromiseState: 'rejected',
PromiseResult: Promise {
PromiseState: 'pending',
PromiseResult: null,
callbacks: []
},
callbacks: []
}
timer: Promise {
PromiseState: 'rejected',
PromiseResult: Promise {
PromiseState: 'fulfilled',
PromiseResult: 'OK',
callbacks: []
},
callbacks: []
}
|
实现 Promise.all()
在 promise.js 中添加如下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = 0 // 成功执行的 promise 的数目
let resultArr = [] // 结果数组
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
++count
// 注意不要使用 resultArr.push(v),这可能导致结果乱序
resultArr[i] = v
if (count === promises.length) {
resolve(resultArr)
}
},
r => {
// 只要有一个失败,立刻更改状态
reject(r)
}
)
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import {Promise} from "./src/promise.js";
let p1 = Promise.resolve(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK1')
}, 1000)
}))
let p2 = Promise.resolve(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK2')
}, 2000)
}))
let p3 = Promise.resolve('OK3')
let result = Promise.all([p1, p2, p3])
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
|
immediate: Promise { PromiseState: 'pending', PromiseResult: null, callbacks: [] }
timer: Promise {
PromiseState: 'fulfilled',
PromiseResult: [ 'OK1', 'OK2', 'OK3' ],
callbacks: []
}
|
实现 Promise.race()
在 promise.js 中添加如下代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
resolve(v)
},
r => {
reject(r)
}
)
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
import {Promise} from "./src/promise.js";
let p1 = Promise.resolve(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK1')
}, 1000)
}))
let p2 = Promise.resolve(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('OK2')
}, 2000)
}))
let p3 = Promise.resolve('OK3')
let p4 = Promise.resolve('OK4')
let result = Promise.race([p1, p2, p3, p4])
console.log('immediate: ', result)
setTimeout(() => {
console.log('timer: ', result)
}, 2000)
|
Output
1
2
3
4
5
6
7
8
9
10
|
immediate: Promise {
PromiseState: 'fulfilled',
PromiseResult: 'OK3',
callbacks: []
}
timer: Promise {
PromiseState: 'fulfilled',
PromiseResult: 'OK3',
callbacks: []
}
|
then 方法传入的回调函数异步执行
修改前
下面代码使用自定义的 Promise 执行
main.js
1
2
3
4
5
6
7
8
9
10
11
12
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
console.log(1)
})
p.then(() => {
console.log(2)
})
console.log(3)
|
Output
下面代码使用官方的 Promise 执行
main.js
1
2
3
4
5
6
7
8
9
10
11
12
|
// import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
console.log(1)
})
p.then(() => {
console.log(2)
})
console.log(3)
|
Output
从上面的两种输出结果可以看出我们自己写的 then 方法如果在执行前 Promise 的状态已经不是 pending 时则立刻执行,即同步执行,而官方的则是延迟执行,即异步执行。
修改后
promise.js
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
149
150
151
152
153
154
155
156
157
158
159
160
161
|
export function Promise(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 异步执行成功的回调
setTimeout(() => {
self.callbacks.forEach(item => item.onResolved(data))
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 异步执行失败的回调
setTimeout(() => {
self.callbacks.forEach(item => item.onRejected(data))
})
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
Promise.prototype.then = function (onResolved, onRejected) {
if (typeof onResolved !== 'function') {
// 实现值传递的关键步骤
onResolved = value => value
}
if (typeof onRejected !== 'function') {
// error: 由于 throw reason 没有返回值,故不能省略大括号
// onRejected = reason => throw reason
// 实现异常穿透的关键步骤
onRejected = reason => {
throw reason
}
}
const self = this
return new Promise((resolve, reject) => {
function handler(callback) {
try {
let result = callback(self.PromiseResult);
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
setTimeout(() => { // 异步执行
handler(onResolved)
})
} else if (this.PromiseState === 'rejected') {
setTimeout(() => { // 异步执行
handler(onRejected)
})
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
handler(onResolved)
},
onRejected: function () {
handler(onRejected)
}
})
}
})
}
Promise.prototype.catch = function (onRejected) {
return this.then(undefined, onRejected)
}
Promise.resolve = function (value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
v => {
resolve(v)
},
r => {
reject(r)
})
} else {
resolve(value)
}
})
}
Promise.reject = function (reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
Promise.all = function (promises) {
return new Promise((resolve, reject) => {
let count = 0 // 成功执行的 promise 的数目
let resultArr = [] // 结果数组
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
++count
// 注意不要使用 resultArr.push(v),这可能导致结果乱序
resultArr[i] = v
if (count === promises.length) {
resolve(resultArr)
}
},
r => {
// 只要有一个失败,立刻更改状态
reject(r)
}
)
}
})
}
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
resolve(v)
},
r => {
reject(r)
}
)
}
})
}
|
main.js
1
2
3
4
5
6
7
8
9
10
11
12
|
import {Promise} from "./src/promise.js";
let p = new Promise((resolve, reject) => {
resolve('OK')
console.log(1)
})
p.then(() => {
console.log(2)
})
console.log(3)
|
Output
将最终结果封装成一个类
promise.js
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
export class Promise {
constructor(executor) {
this.PromiseState = 'pending'
this.PromiseResult = null
// 保存回调函数
this.callbacks = []
const self = this
function resolve(data) {
if (self.PromiseState !== 'pending') return
// 1. 修改对象的状态
self.PromiseState = 'fulfilled'
// 2. 设置对象结果值
self.PromiseResult = data
// 异步执行成功的回调
setTimeout(() => {
self.callbacks.forEach(item => item.onResolved(data))
})
}
function reject(data) {
if (self.PromiseState !== 'pending') return
self.PromiseState = 'rejected'
self.PromiseResult = data
// 异步执行失败的回调
setTimeout(() => {
self.callbacks.forEach(item => item.onRejected(data))
})
}
// 同步调用执行器
try {
executor(resolve, reject)
} catch (e) {
reject(e)
}
}
then(onResolved, onRejected) {
if (typeof onResolved !== 'function') {
// 实现值传递的关键步骤
onResolved = value => value
}
if (typeof onRejected !== 'function') {
// error: 由于 throw reason 没有返回值,故不能省略大括号
// onRejected = reason => throw reason
// 实现异常穿透的关键步骤
onRejected = reason => {
throw reason
}
}
const self = this
return new Promise((resolve, reject) => {
function handler(callback) {
try {
let result = callback(self.PromiseResult);
if (result instanceof Promise) {
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
resolve(result)
}
} catch (e) {
reject(e)
}
}
if (this.PromiseState === 'fulfilled') {
// 处理 onResolved 执行出现异常的情况
setTimeout(() => { // 异步执行
handler(onResolved)
})
} else if (this.PromiseState === 'rejected') {
setTimeout(() => { // 异步执行
handler(onRejected)
})
} else if (this.PromiseState === 'pending') {
// 保存回调函数 -------------------- important
this.callbacks.push({
onResolved: function () {
handler(onResolved)
},
onRejected: function () {
handler(onRejected)
}
})
}
})
}
catch(onRejected) {
return this.then(undefined, onRejected)
}
static resolve(value) {
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(
v => {
resolve(v)
},
r => {
reject(r)
})
} else {
resolve(value)
}
})
}
static reject(reason) {
return new Promise((resolve, reject) => {
reject(reason)
})
}
static all(promises) {
return new Promise((resolve, reject) => {
let count = 0 // 成功执行的 promise 的数目
let resultArr = [] // 结果数组
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
++count
// 注意不要使用 resultArr.push(v),这可能导致结果乱序
resultArr[i] = v
if (count === promises.length) {
resolve(resultArr)
}
},
r => {
// 只要有一个失败,立刻更改状态
reject(r)
}
)
}
})
}
static race(promises) {
return new Promise((resolve, reject) => {
for (let i = 0; i < promises.length; ++i) {
promises[i].then(
v => {
resolve(v)
},
r => {
reject(r)
}
)
}
})
}
}
|