用最少的代码手工实现一个Promise,5分钟看懂
2023-11-07 01:46:59
**## **
**## **
序言
在现代软件开发中,异步编程已经成为一种不可或缺的技术。它允许程序在不阻塞主线程的情况下执行耗时的操作,从而提高程序的响应速度和并发能力。而Promise,作为一种异步编程的利器,在JavaScript中扮演着至关重要的角色。它不仅可以简化异步编程的代码结构,还可以让代码更加清晰易读。
Promise的原理与实现
1. Promise的构造函数
Promise是一个构造函数,它接受一个执行器函数作为参数。执行器函数有两个参数,分别是resolve和reject。resolve用于将Promise的状态从pending变为fulfilled,并携带一个值作为结果;reject用于将Promise的状态从pending变为rejected,并携带一个值作为错误原因。
function Promise(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
2. Promise的状态
Promise的状态可以分为三种:pending、fulfilled和rejected。
- pending:表示Promise尚未完成,处于等待状态。
- fulfilled:表示Promise已完成,并且成功执行。
- rejected:表示Promise已完成,但执行过程中发生了错误。
3. Promise的方法
Promise提供了几个有用的方法,包括:
- then:用于注册回调函数,当Promise的状态改变时,回调函数将被调用。
- catch:用于注册错误处理函数,当Promise的状态变为rejected时,错误处理函数将被调用。
- finally:用于注册一个回调函数,无论Promise的状态如何,该回调函数都会被调用。
4. Promise的链式调用
Promise支持链式调用,这使得代码更加简洁和易读。链式调用是通过then方法实现的。then方法返回一个新的Promise,这个新的Promise的状态取决于前一个Promise的状态。如果前一个Promise的状态是fulfilled,则新Promise的状态也是fulfilled,并且新Promise的值是前一个Promise的值。如果前一个Promise的状态是rejected,则新Promise的状态也是rejected,并且新Promise的错误原因是前一个Promise的错误原因。
promise1
.then(function(value) {
return value + 1;
})
.then(function(value) {
console.log(value); // 输出 2
});
手工实现一个Promise
手工实现一个Promise并不困难,只需要几个简单的步骤。
1. 创建Promise构造函数
首先,我们需要创建一个Promise构造函数。这个构造函数接受一个执行器函数作为参数。执行器函数有两个参数,分别是resolve和reject。resolve用于将Promise的状态从pending变为fulfilled,并携带一个值作为结果;reject用于将Promise的状态从pending变为rejected,并携带一个值作为错误原因。
function Promise(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
2. 实现Promise的方法
接下来,我们需要实现Promise的方法,包括then、catch和finally。
- then方法:then方法接受两个参数,分别是fulfilledCallback和rejectedCallback。当Promise的状态改变时,fulfilledCallback或rejectedCallback将被调用。
Promise.prototype.then = function(fulfilledCallback, rejectedCallback) {
if (typeof fulfilledCallback !== 'function') {
fulfilledCallback = function(value) {
return value;
};
}
if (typeof rejectedCallback !== 'function') {
rejectedCallback = function(reason) {
throw reason;
};
}
var newPromise = new Promise(function() {});
this.onFulfilledCallbacks.push(function() {
var value = fulfilledCallback(this.value);
resolve(newPromise, value);
});
this.onRejectedCallbacks.push(function() {
var reason = rejectedCallback(this.reason);
reject(newPromise, reason);
});
return newPromise;
};
- catch方法:catch方法接受一个参数,是一个错误处理函数。当Promise的状态变为rejected时,错误处理函数将被调用。
Promise.prototype.catch = function(rejectedCallback) {
return this.then(undefined, rejectedCallback);
};
- finally方法:finally方法接受一个参数,是一个回调函数。无论Promise的状态如何,该回调函数都会被调用。
Promise.prototype.finally = function(callback) {
return this.then(
function() {
callback();
},
function() {
callback();
}
);
};
3. 实现resolve和reject函数
最后,我们需要实现resolve和reject函数。resolve函数用于将Promise的状态从pending变为fulfilled,并携带一个值作为结果;reject函数用于将Promise的状态从pending变为rejected,并携带一个值作为错误原因。
function resolve(promise, value) {
if (promise.state !== 'pending') {
return;
}
promise.state = 'fulfilled';
promise.value = value;
for (var i = 0; i < promise.onFulfilledCallbacks.length; i++) {
promise.onFulfilledCallbacks[i]();
}
}
function reject(promise, reason) {
if (promise.state !== 'pending') {
return;
}
promise.state = 'rejected';
promise.reason = reason;
for (var i = 0; i < promise.onRejectedCallbacks.length; i++) {
promise.onRejectedCallbacks[i]();
}
}
结语
以上就是手工实现一个Promise的全部过程。通过这个过程,我们对Promise的原理和实现有了更深入的理解。掌握了Promise的原理和实现,我们就可以在实际项目中熟练地使用Promise,从而编写出更加优雅和易维护的异步代码。