2025-12-19 日报 Day305

Yuyang 前端小白🥬

今日的鸡汤

promise实现笔记

promise的基本使用方法:
promise的三种状态: pending, fulfilled, rejected;

基本使用方法:
1、创建一个Promise执行异步任务:

1
2
3
4
5
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("成功");
}, 1000);
})

2、消费 Promise(then/catch)

1
2
3
4
5
p.then(result => {
console.log(result);
}).catch(error => {
console.error(error);
})

3、Promise的一些其他用法:

  • promise.resolve/reject
  • promise.all
    1
    Promise.all([promise1, promise2, ...]).then();
  • promise.race
    1
    Promise.race([promise1, promise2, ...]).then();
  • promise.allSettled
  • promise.any

简单版

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
function MyPromise(fn){
// 存储示例
let self = this;
// 存储promise信息
let value = null;
let error = null;
// 存储promise状态
let status = null;

function resolve(value) {
this.value = value;
this.status = "fulfilled";
this.onFulfilled(self.value);
}

function reject(error){
this.error = error;
this.status = "rejected";
this.onRejected(self.error)
}

fn(resolve, reject)
}

MyPromise.prototype.then = function(onFulfilled, onRejected){
this.onFulfilled = onFulfilled;
this.onRejected = onRejected;
}

module.exports = MyPromise;

但其实这个版本的实现是有问题的:

  • then的注册晚了
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
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';

class Promise {
constructor(executor){
// 初始化状态
this.status = PENDING;
// 存储异步状态
this.value = undefined;
this.reason = undefined;

const resolve = value => {
if(this.status === PENDING){
this.status = FULFILLED;
this.value = value;
}
}

const reject = reason => {
if(this.status === PENDING){
this.status = REJECTED;
this.reason = reason;
}
}
}

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

then(onFulfilled, onRejected){
// then是微任务 这里用setTimeout模拟
setTimeout(() => {
if(this.status === FULFILLED){
onFulfilled(this.value);
} else if(this.status === REJECTED){
onRejected(this.reason);
}
}, 0);
}
}

const promise = new Promise((resolve, reject) => {
Math.random() < 0.5 ? resolve(1) : reject(-1);
}).then(res=>console.log(res),err=>console.error(err))

当前promise实现存在的问题:

  • promise内部异步代码执行的问题:promise内部如果有异步代码执行后才resolve,then不会等待异步代码执行完毕会直接执行
  • promise链式调用问题
  • 值传递

因此需要新增onFulfilledCallbacks、onRejectedCallbacks维护成功、失败的任务执行队列

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
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
constructor(executor){
// 初始化状态
this.state = PENDING;

// 失败和成功状态
this.value = undefined;
this.reason = undefined;

// 成功回调函数队列
this.onFulfilledCallbacks = [];

// 失败回调函数队列
this.onRejectedCallbacks = [];

const resolve = value => {
if(this.state === PENDING){
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
}

const reject = reason => {
if(this.state === PENDING){
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
}

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

then(onFulfilled, onRejected){
// then是微任务,这里用setTimeout模拟
setTimeout(()=>{
if(this.status === PENDING){
this.onFulfilledCallbacks.push(onFulfilled);
this.onRejectedCallbacks.push(onRejected);
}else if(this.status === FULFILLED){
onFulfilled(this.value);
}else if(this.status === REJECTED){
onRejected(this.reason);
}
})
}
}
}

const promise = new Promise((resolve, reject) => {
setTimeout(() => resolve(1), 1000);
}).then(res=>console.log(res))

实现链式调用:promise的一大优势就是支持链式调用,具体来说就是then方法的具体实现,实际上就是返回了一个Promise:

  • 保存之前promise的实例引用,即保存this
  • 根据then回调函数执行的结果,决定新的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
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
constructor(executor){
// 初始化状态
this.state = PENDING;

// 失败和成功状态
this.value = undefined;
this.reason = undefined;

// 成功回调函数队列
this.onFulfilledCallbacks = [];

// 失败回调函数队列
this.onRejectedCallbacks = [];

const resolve = value => {
if(this.state === PENDING){
this.state = FULFILLED;
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
}

const reject = reason => {
if(this.state === PENDING){
this.state = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
}

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

then(onFulfilled, onRejected){
// then是微任务,这里用setTimeout模拟
const self = this;
return new Promise((resolve,reject)=>{
if(self.status === PENDING){
self.onFulfilledCallbacks.push(()=>{
try{
setTimeout(()=>{
const result = onFulfilled(self.value);

// 分两种情况:
// 1、回调函数返回的是promise,执行then操作
// 2、如果不是promise,调用新promise的resolve函数
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
}catch(e){
reject(e);
}
})
self.onRejectedCallbacks.push(()=>{
try{
setTimeout(()=>{
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
})
}catch(e){
reject(e);
}
})
}else if(self.status === FULFILLED){
setTimeout(()=>{
try{
const result = onFulfilled(self.value);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
}catch(e){
reject(e);
}
})
}else if(self.status === REJECTED){
setTimeout(()=>{
try{
const result = onRejected(self.reason);
result instanceof Promise ? result.then(resolve, reject) : resolve(result);
}catch(e){
reject(e);
}
})
}
})
}


}
}
评论
此页目录
2025-12-19 日报 Day305