TS与class构建简易Promise,揭开异步编程面纱
2024-01-27 08:52:38
Promise,一个神奇的 JavaScript 对象,它能让你处理异步操作变得更加轻松。它提供了 then 和 catch 方法,允许你在异步操作成功或失败时执行不同的操作。使用Promise,你可以避免回调地狱,让你的代码更加易读和可维护。
现在,我们来使用 TypeScript 和 class 来实现一个简易的Promise。我们首先定义一个Promise类:
class Promise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
return new Promise((resolve, reject) => {
if (this.state === 'pending') {
this.onFulfilledCallbacks.push(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (error) {
reject(error);
}
});
} else if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (error) {
reject(error);
}
}, 0);
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
resolve(value) {
if (this.state !== 'pending') {
return;
}
this.state = 'fulfilled';
this.value = value;
setTimeout(() => {
this.onFulfilledCallbacks.forEach(callback => callback());
}, 0);
}
reject(reason) {
if (this.state !== 'pending') {
return;
}
this.state = 'rejected';
this.reason = reason;
setTimeout(() => {
this.onRejectedCallbacks.forEach(callback => callback());
}, 0);
}
}
这个Promise类的构造函数接收一个executor函数作为参数,executor函数有两个参数,分别是resolve和reject。resolve函数用于将Promise的状态从pending变为fulfilled,并传入一个参数value。reject函数用于将Promise的状态从pending变为rejected,并传入一个参数reason。
Promise类还定义了then方法、catch方法、resolve方法和reject方法。then方法用于为Promise添加回调函数,当Promise的状态改变时,这些回调函数就会被执行。catch方法用于为Promise添加一个错误处理回调函数,当Promise被reject时,这个回调函数就会被执行。resolve方法用于将Promise的状态从pending变为fulfilled,并传入一个参数value。reject方法用于将Promise的状态从pending变为rejected,并传入一个参数reason。
现在,我们就可以使用这个Promise类来实现异步操作了。例如,我们可以使用Promise来实现一个简单的AJAX请求:
const promise = new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/api/data');
xhr.onload = () => {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => {
reject(xhr.statusText);
};
xhr.send();
});
promise.then(data => {
console.log(data);
}).catch(error => {
console.log(error);
});
这个代码首先创建一个Promise对象,然后使用XMLHttpRequest对象发送一个AJAX请求。当AJAX请求成功时,Promise的状态会变成fulfilled,并且将请求到的数据作为参数传递给then方法的回调函数。当AJAX请求失败时,Promise的状态会变成rejected,并且将错误信息作为参数传递给catch方法的回调函数。
使用Promise,你可以轻松地处理异步操作,让你的代码更加易读和可维护。现在,你已经学会了如何使用TypeScript和class来实现一个简易的Promise,你可以用它来构建更强大的异步应用程序。