• 简易版 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
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';

function MyPromise(fn) {
const that = this; // 代码可能会异步执行,用于获取正确的this对象
that.state = PENDING;
that.value = null; // 用于保存resolve或者reject中传入的值
that.resolvedCallbacks = [];
that.rejectedCallbacks = []; // 保存then中的回调,状态改变时使用

function resolve(value) {
//只有等待状态才可以改变状态
if (that.state === PENDING) {
that.state = RESOLVED;
that.value = value; // 调用then的时候value需要往下传递
that.resolvedCallbacks.map(cb => cb(that.value)); // 执行回调
}
}

function reject(value) {
if (that.state === PENDING) {
that.state = REJECTED;
that.value = value;
that.rejectedCallbacks.map(cb => cb(that.value));
}
}

// 执行Promise中传入的函数
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}

MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this;
// 检测参数是否是函数类型,如果不是则创建一个函数赋值给对应的参数
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected =
typeof onRejected === 'function'
? onRejected
: r => {
throw new Error(r);
};
if (that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled);
that.rejectedCallbacks.push(onRejected);
}

if (that.state === RESOLVED) {
onFulfilled(that.value);
}
if (that.state === REJECTED) {
onRejected(that.value);
}
};

// 调用
new MyPromise((resolve, reject) => {
let a = 0;
if (a === 1) {
resolve(a);
} else {
reject('error啦');
}
}).then(
value => {
console.log('success', value);
},
err => {
console.log('err', 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
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
try {
module.exports = Promise;
} catch (e) {}

function Promise(executor) {
var self = this;

self.status = 'pending';
self.onResolvedCallback = [];
self.onRejectedCallback = [];

function resolve(value) {
if (value instanceof Promise) {
return value.then(resolve, reject);
}
setTimeout(function() {
// 异步执行所有的回调函数
if (self.status === 'pending') {
self.status = 'resolved';
self.data = value;
for (var i = 0; i < self.onResolvedCallback.length; i++) {
self.onResolvedCallback[i](value);
}
}
});
}

function reject(reason) {
setTimeout(function() {
// 异步执行所有的回调函数
if (self.status === 'pending') {
self.status = 'rejected';
self.data = reason;
for (var i = 0; i < self.onRejectedCallback.length; i++) {
self.onRejectedCallback[i](reason);
}
}
});
}

try {
executor(resolve, reject);
} catch (reason) {
reject(reason);
}
}

function resolvePromise(promise2, x, resolve, reject) {
var then;
var thenCalledOrThrow = false;

if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise!'));
}

if (x instanceof Promise) {
if (x.status === 'pending') {
//because x could resolved by a Promise Object
x.then(function(v) {
resolvePromise(promise2, v, resolve, reject);
}, reject);
} else {
//but if it is resolved, it will never resolved by a Promise Object but a static value;
x.then(resolve, reject);
}
return;
}

if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
try {
then = x.then; //because x.then could be a getter
if (typeof then === 'function') {
then.call(
x,
function rs(y) {
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
return resolvePromise(promise2, y, resolve, reject);
},
function rj(r) {
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
return reject(r);
}
);
} else {
resolve(x);
}
} catch (e) {
if (thenCalledOrThrow) return;
thenCalledOrThrow = true;
return reject(e);
}
} else {
resolve(x);
}
}

Promise.prototype.then = function(onResolved, onRejected) {
var self = this;
var promise2;
onResolved =
typeof onResolved === 'function'
? onResolved
: function(v) {
return v;
};
onRejected =
typeof onRejected === 'function'
? onRejected
: function(r) {
throw r;
};

if (self.status === 'resolved') {
return (promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
// 异步执行onResolved
try {
var x = onResolved(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
}));
}

if (self.status === 'rejected') {
return (promise2 = new Promise(function(resolve, reject) {
setTimeout(function() {
// 异步执行onRejected
try {
var x = onRejected(self.data);
resolvePromise(promise2, x, resolve, reject);
} catch (reason) {
reject(reason);
}
});
}));
}

if (self.status === 'pending') {
return (promise2 = new Promise(function(resolve, reject) {
self.onResolvedCallback.push(function(value) {
try {
var x = onResolved(value);
resolvePromise(promise2, x, resolve, reject);
} catch (r) {
reject(r);
}
});

self.onRejectedCallback.push(function(reason) {
try {
var x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (r) {
reject(r);
}
});
}));
}
};

Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};

Promise.deferred = Promise.defer = function() {
var dfd = {};
dfd.promise = new Promise(function(resolve, reject) {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};