从小白视角快速上手 Promise、Async/await,并实现手撕代码
2023-11-01 01:59:43
JavaScript 的世界,从小白到高手,你我皆可为王。
写在前面
在前端开发中,我们经常会遇到异步操作,比如网络请求、定时器等。这些操作的特点是,它们不会立即返回结果,而是需要等待一段时间后才能得到结果。为了处理异步操作,我们可以使用回调函数、Promise和Async/await等方式。
本文将从小白的角度出发,带你快速上手Promise、Async/await,并实现手撕代码。
一、异步操作与回调函数
异步操作是指不会立即返回结果的操作,比如网络请求、定时器等。这些操作需要等待一段时间后才能得到结果。
回调函数是指当异步操作完成时被调用的函数。回调函数通常作为异步操作函数的参数传入。当异步操作完成时,异步操作函数会调用回调函数,并将结果作为参数传递给回调函数。
回调函数的写法如下:
function callback(result) {
// 异步操作完成后的处理逻辑
}
二、Promise
Promise是一种用于处理异步操作的更高级的方式。Promise对象代表一个异步操作的结果,它可以处于三种状态:
- pending(等待): 异步操作尚未完成。
- fulfilled(已完成): 异步操作已完成,并且成功返回了结果。
- rejected(已拒绝): 异步操作已完成,并且失败了。
我们可以使用Promise对象的then方法来处理异步操作的结果。then方法接受两个参数,分别是fulfilledHandler和rejectedHandler。当异步操作成功完成时,fulfilledHandler会被调用,并接收异步操作的结果作为参数。当异步操作失败时,rejectedHandler会被调用,并接收异步操作的错误信息作为参数。
Promise对象的写法如下:
const promise = new Promise((resolve, reject) => {
// 异步操作
if (success) {
resolve(result);
} else {
reject(error);
}
});
promise.then(fulfilledHandler, rejectedHandler);
三、Async/await
Async/await是ES8中引入的异步编程语法。Async/await可以使异步代码看起来像同步代码一样。
要使用Async/await,我们需要先使用async声明一个函数。在async函数中,我们可以使用await关键字来等待异步操作完成。await关键字后面的表达式必须是一个Promise对象。当await关键字后面的Promise对象完成时,await关键字后面的代码才会执行。
Async/await的写法如下:
async function myFunction() {
const result = await promise;
// 异步操作完成后的处理逻辑
}
四、手撕代码
手撕代码是指不使用任何库或框架,自己实现代码。我们可以使用手撕代码来实现Promise和Async/await。
实现Promise
class Promise {
constructor(executor) {
this.state = 'pending';
this.result = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (result) => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.result = result;
this.onFulfilledCallbacks.forEach(callback => callback(result));
};
const reject = (error) => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.result = error;
this.onRejectedCallbacks.forEach(callback => callback(error));
};
executor(resolve, reject);
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
if (this.state === 'fulfilled') {
onFulfilled(this.result);
} else if (this.state === 'rejected') {
onRejected(this.result);
} else {
this.onFulfilledCallbacks.push(() => {
onFulfilled(this.result);
});
this.onRejectedCallbacks.push(() => {
onRejected(this.result);
});
}
});
}
}
实现Async/await
function asyncFunction(generator) {
return new Promise((resolve, reject) => {
const gen = generator();
function handleNext(value) {
const result = gen.next(value);
if (result.done) {
resolve(result.value);
} else {
result.value.then(handleNext, handleReject);
}
}
function handleReject(error) {
gen.throw(error);
}
handleNext();
});
}
五、总结
Promise和Async/await都是处理异步操作的有效方法。Promise对象可以表示异步操作的结果,并可以使用then方法来处理异步操作的结果。Async/await可以使异步代码看起来像同步代码一样。
本文从小白的角度出发,带你快速上手Promise、Async/await,并实现手撕代码。希望本文对你有帮助。