1. Promise基本概念
Promise是ES6中新增的一种处理异步操作的方法,在之前的回调函数和事件监听中,处理异步操作时代码通常较为复杂,Promise呈现了更加优雅的解决方案。
Promise解决的问题: 回调地狱问题
回调地狱是指在回调函数嵌套过多导致代码难以阅读和维护,示例代码如下:
async1(function () {
async2(function () {
async3(function () {
async4(function () {
// code
});
});
});
});
使用Promise可以有效地避免这种现象,使代码更简洁、清晰。
2. Promise基本使用
2.1 Promise构造函数
Promise的构造函数接受一个函数作为参数,该函数又接受两个函数作为参数。该参数函数中的两个函数分别被命名为resolve和reject。若操作成功,调用resolve并传递操作结果;若操作失败,调用reject并传递失败原因。
const promise = new Promise((resolve, reject) => {
if (operationSuccess) {
resolve(result);
} else {
reject('operation failed');
}
});
2.2 Promise异步操作
使用Promise时,异步操作通常放在Promise中。Promise提供了then和catch方法,分别对应resolve和reject传递的信息。then返回Promise对象,使得操作可以被连续执行。
promise.then(result => {
// 成功时执行
}).catch(error => {
// 失败时执行
});
2.3 Promise.all静态方法
Promise.all接受一个Promise对象数组,当所有Promise都返回时返回结果数组,若有任意一个Promise被rejected,则Promise.all返回失败结果。
Promise.all([promise1, promise2, promise3])
.then(resultArray => {
// 所有Promise都成功时执行
})
.catch(error => {
// 若任意一个Promise失败则执行
});
2.4 Promise.race静态方法
Promise.race接受一个Promise对象数组,当任意一个Promise对象返回时返回该结果。若第一个返回的结果是Promise对象,则Promise.race返回该Promise的结果。
Promise.race([promise1, promise2, promise3])
.then(result => {
// 其中一个Promise对象返回时执行
})
.catch(error => {
// 第一个返回值为异常或Promise对象的Promise对象被Rejected时执行
});
3. Promise应用示例
3.1 Ajax请求
传统的ajax请求通常使用回调函数,但在使用Promise之后ajax请求可以完全使用Promise实现。
function ajax(url, method, data) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(JSON.parse(this.responseText));
} else {
reject('request failed');
}
}
};
xhr.send(data);
});
}
ajax('http://example.com/api', 'get', null)
.then(result => {
// 成功时执行
})
.catch(error => {
// 失败时执行
});
3.2 延迟执行
setTimeout操作通常使用回调函数,但也可以使用Promise实现。
function delay(t) {
return new Promise(resolve => {
setTimeout(resolve, t);
});
}
delay(1000).then(() => {
// 一秒后执行
});
3.3 图片预加载
图片预加载通常使用回调函数,在使用Promise后可以使用更加优美的方式来实现。
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = document.createElement('img');
img.addEventListener('load', () => {
resolve(img);
});
img.addEventListener('error', () => {
reject('load image failed');
});
img.src = url;
});
}
loadImage('http://example.com/images/image.jpg')
.then(img => {
// 加载成功时执行
})
.catch(error => {
// 加载失败时执行
});
4. 总结
Promise为处理异步操作提供了一种优美而高效的解决方案,使用Promise可以避免回调地狱问题,并使代码更加清晰简洁。Promise特别适合用于处理ajax请求、延迟、图片预加载等操作。