banner
NEWS LETTER

经典题记录,手写 promise

Scroll down

经典题记录,手写 promise

什么是 promise

promise 译为承诺,在前端当中主要解决 “回调地狱” 问题:

他是一种异步编程解决方案,可以理解为一个高阶函数工厂,使用 Promise 的构造函数将输入的一个需要异步处理的函数包装一个 有多种 promise 功能的盒子(object),然后优雅地解决异步问题。

这里有个点,使用 promise 的 then 方法将多层嵌套改为链式调用,让逻辑清晰,事实上是降低了开发难度的。

一个成熟的 Promise 对象都有啥

  1. 首先来看一个原生 Promise 调用的例子。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let p = new Promise((resolve,reject) => {
setTimeout(() => {
console.log('run async ')
resolve('resolve')
},1000);
})

p.then((res) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('run async then 1')
resolve('one plus')
},1000);
})
}).then((res) => {
console.log('get then2 res',res)
})
  1. Promise 有三种状态:
    a. pending (等待)
    b. resolved (成功)
    c. rejected (失败)

从 pending 开始,一经改变就不能再改,要么成功,要么失败。

  1. 响应处理状态的方法:
    a. resolve
    b. reject

这两个方法传给异步函数(executor),也就是处理我们的 ajax 请求等业务的函数。

  1. 以及 Promise 的灵魂:处理异步结束的方法:
    a. then
    b. finally

  2. 最后还有处理错误的方法,能处理错误是系统稳定性的保证措施之一:
    a. catch

  3. 最后的最后是一些官方对 Promise 的定义:
    a. promise规范中要求所有的infulfilled, inrejected都要异步执行

实现一个 Promise

为了免于冲突自己的 Promise 取名为: _Promise

Promise.all

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
41   _Promise.all = function(arr) {
42
43 if (!(arr instanceof Array)) {
44 throw 'arr must be _Promise Array';
45 return;
46 }
47
48 return _Promise(function(resolve, reject) {
49 var dataarr = {};
50 var len = arr.length;
51 for (var i = 0; i < len; i++) {
52 (function(c) {
53 console.log(arr[c]);
54 arr[c].then(function(data) {
55 dataarr[c] = data;
56 len--;
57 if (len == 0) {
58 var data = new Array(len);
59 for (var item in dataarr) {
60 data[item] = dataarr[item];
61 }
62 resolve(data);
63 }
64
65 }, function(error) {
66 reject(error);
67 })
68 })(i)
69 }
70 })
71 }
72

这是我实现的简易版:

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
class _Promise {
constructor (executor) {
this.status = 'pending' // pending , resolved, rejected
this.value = null // 处理异步后的值
this.reason = null // 异常保留值
this.resolveCallBackList = []
this.rejectCallBackList = []
this.isHasCatch = false
this.CatchFunc = null
let self = this

function resolve(val) {
if (self.status === 'pending') {
self.status = 'resolved'
self.value = val
self.resolveCallBackList.forEach(fun =>fun());
}
}

function reject(val) {
if (self.status === 'pending') {
self.status = 'rejected'
self.value = val
self.rejectCallBackList.forEach(fun => fun());
}
}
try {
executor(resolve,reject)
} catch (error) {
console.log('init ')
if (this.isHasCatch) {
this.CatchFunc(error)
} else {
reject(error)
}
}
}

then(infulfilled, inrejected) {
let self = this
let p2 ;

infulfilled = typeof infulfilled === 'function' ? infulfilled : function (val) {
return val
}
inrejected = typeof inrejected === 'function' ? inrejected : function (err) {
throw err
}

if (self.status === 'resolve') {
p2 = new _Promise((resolve, reject) => {
setTimeout(() => {
try {
let x = infulfilled(self.value)
self.resolvePromise(p2, x, resolve, reject)
} catch (error) {
console.log('then resolve ')
if (this.isHasCatch) {
this.CatchFunc(error)
} else {
reject(error)
}
}
});
})
}

if (self.status === 'rejected') {
p2 = new _Promise((resolve,reject) => {
setTimeout(() => {
try {
let x = inrejected(self.reason)
self.resolvePromise(p2,x,resolve,reject)
} catch (error) {
reject(error)
}
});
})
}

if (self.status === 'pending') {
p2 = new _Promise((resolve,reject) => {
setTimeout(() => {
try {
self.resolveCallBackList.push(() => {
let x = infulfilled(self.value)
self.resolvePromise(p2,x,resolve,reject)
})

self.rejectCallBackList.push(() => {
let x = inrejected(self.reason)
self.resolvePromise(p2,x,resolve,reject)
})
} catch (error) {
reject(error)
}
});
})
}
return p2
}

resolvePromise(p2,x,resolve,reject) {
let self = this
if (p2 === x && x !== undefined) reject(new Error('类型错误'))

if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
let then = x.then
if (typeof then === 'function') {
then.call(x, function (y) {
self.resolvePromise(p2,y,resolve,reject)
})
} else {
resolve(x)
}
} catch (error) {
reject(error)
}
} else {
resolve(x)
}
}

catch(handleError) {
return this.then(undefined,handleError)
}
}

知识决定高度,现在高度低,多写多练。

其他文章
目录导航 置顶
  1. 1. 什么是 promise
  2. 2. 一个成熟的 Promise 对象都有啥
  3. 3. 实现一个 Promise