下面是“JavaScript自定义Promise实现流程”的完整攻略。
Promise简介
Promise是ES6新增的异步编程解决方案,主要用于解决回调地狱问题。Promise对象代表一个异步操作,可以将异步操作的执行结果以回调函数的形式传递给程序员,从而实现异步编程。
自定义Promise实现流程
下面我们将介绍如何实现一个简单的Promise,包括Promise的三个状态和then方法的实现。
Promise的三个状态
Promise有三个状态:pending
(进行中)、fulfilled
(已成功)、rejected
(已失败)。当Promise处于pending
状态时,可以转换为fulfilled
或rejected
状态,但状态一旦转换就不能再改变。从pending
状态转换到fulfilled
状态,说明异步操作已经成功完成;从pending
状态转换到rejected
状态,说明异步操作已经失败。
下面是一个简单的Promise实现:
class MyPromise {
constructor(fn) {
this.promiseStatus = 'pending'; // Promise状态
this.promiseValue = null; // Promise传递的值
this.promiseResolveFunc = null; // 执行成功的回调函数
this.promiseRejectFunc = null; // 执行失败的回调函数
const resolve = (value) => {
if (this.promiseStatus === 'pending') {
this.promiseStatus = 'fulfilled';
this.promiseValue = value;
if (typeof this.promiseResolveFunc === 'function') {
this.promiseResolveFunc(this.promiseValue); // 执行成功的回调函数
}
}
};
const reject = (value) => {
if (this.promiseStatus === 'pending') {
this.promiseStatus = 'rejected';
this.promiseValue = value;
if (typeof this.promiseRejectFunc === 'function') {
this.promiseRejectFunc(this.promiseValue); // 执行失败的回调函数
}
}
};
try {
fn(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
if (this.promiseStatus === 'fulfilled') {
onFulfilled(this.promiseValue);
} else if (this.promiseStatus === 'rejected') {
onRejected(this.promiseValue);
} else {
this.promiseResolveFunc = onFulfilled;
this.promiseRejectFunc = onRejected;
}
}
}
上面的代码定义了一个MyPromise
类,该类接受一个函数作为参数,在函数中执行异步操作,并根据异步操作的结果来改变Promise的状态。在then
方法中,根据Promise的状态来执行相应的回调函数。
现在来看一个简单的应用案例:
new MyPromise((resolve, reject) => {
const timer = setTimeout(() => {
clearTimeout(timer);
const num = Math.random();
if (num > 0.5) {
resolve(num);
} else {
reject(num);
}
}, 1000);
}).then(
(value) => console.log(`成功:${value}`),
(value) => console.log(`失败:${value}`)
);
上面的代码中,我们new了一个MyPromise
对象,传入一个回调函数,函数中执行了一个异步操作:生成一个随机数并判断大于0.5则执行resolve回调,否则执行reject回调。最终,我们将then方法链式调用,在成功或失败时分别输出相应的内容。
示例说明一
下面是一个加载图片的示例:
function loadImg(url) {
return new MyPromise((resolve, reject) => {
const img = new Image();
img.onload = function () {
resolve(img);
};
img.onerror = function () {
reject(`图片加载失败:${url}`);
};
img.src = url;
});
}
loadImg('https://source.unsplash.com/random/800x600').then(
(img) => document.body.appendChild(img),
(msg) => console.log(msg)
);
上面的代码中,我们定义了一个loadImg
函数,该函数接受一个图片地址作为参数,并返回一个MyPromise
对象。在函数内部,我们创建了一个Image
对象并设置其onload
和onerror
回调函数,在加载成功时执行resolve
回调,在加载失败时执行reject
回调。最后,我们将loadImg
函数的返回值调用then
方法并链式调用执行回调。
实例说明二
下面是一个异步请求的示例:
function ajax(url, method, params) {
return new MyPromise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(new Error(xhr.statusText));
}
}
};
xhr.onerror = function () {
reject(new Error(xhr.statusText));
};
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(params);
});
}
ajax('/api/user', 'POST', { name: '张三', age: 18 }).then(
(res) => console.log(res),
(err) => console.log(err)
);
上面的代码中,我们定义了一个ajax
函数,该函数接受请求的地址、请求方法以及请求参数,并返回一个MyPromise
对象。在函数内部,我们使用XMLHttpRequest
对象发起异步请求,并设置其onreadystatechange
和onerror
回调函数。在请求成功时执行resolve
回调,在请求失败时执行reject
回调。最后,我们将ajax
函数的返回值调用then
方法并链式调用执行回调。
总结
通过本文的介绍,我们学习了如何实现一个简单的Promise,包括Promise的三个状态和then方法的实现。我们还通过两个示例分别介绍了如何使用自定义Promise来加载图片和发起异步请求。希望读者可以从中学习到有用的知识,并在自己的项目中应用Promise来优化异步编程。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript自定义Promise实现流程 - Python技术站