深入学习 JavaScript 中的 Promise
什么是 Promise
Promise 是一种处理异步操作的机制。它将异步操作包装成一个对象,使得我们可以像同步操作一样进行编程。Promise 对象可以表示一个异步操作的“未来结果”,并且提供了一些方法来处理这个“未来结果”的返回值或者错误信息。
Promise 的状态
Promise 有 3 种状态:
- pending - 初始状态,不是 fulfilled 也不是 rejected。
- fulfilled - 意味着操作成功完成,返回了相应的值。
- rejected - 意味着操作失败,返回了相应的错误信息。
Promise 的基本用法
Promise 的基本用法包括 Promise 的创建、Promise 的 then 方法,以及 Promise 的 catch 方法。
Promise 的创建
const promise = new Promise((resolve, reject) => {
// 异步操作
const result = doSomething();
if (result.success) {
resolve(result.value);
} else {
reject(result.error);
}
});
上面代码中,Promise 接受一个函数作为参数,这个函数被称为 Promise 的“执行函数”,它接受两个参数 resolve 和 reject。resolve 负责将 Promise 的状态从 pending 转变为 fulfilled,reject 负责将 Promise 的状态从 pending 转变为 rejected。
Promise 的 then 方法
promise.then(
result => {
console.log('操作成功:', result);
},
error => {
console.log('操作失败:', error);
}
);
then 方法接受两个参数:成功回调和失败回调。当 Promise 的状态变为 fulfilled 时,会执行成功回调,可将结果传递给该回调。当 Promise 的状态变为 rejected 时,会执行失败回调,可将错误信息传递给该回调。
Promise 的 catch 方法
promise.catch(error => {
console.log('操作失败:', error);
});
catch 方法只接受一个参数:失败回调。有时候我们只关心 Promise 的失败情况,那么就可以使用 catch 方法来代替 then 方法中的第二个参数。
Promise 的高级用法
Promise.all 方法
const promise1 = Promise.resolve('Promise 1');
const promise2 = Promise.resolve('Promise 2');
const promise3 = Promise.resolve('Promise 3');
Promise.all([promise1, promise2, promise3]).then(results => {
console.log(results);
});
Promise.all 方法接受一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。当所有的 Promise 对象都成功执行时,Promise.all 返回的 Promise 对象的状态变为 fulfilled,并返回一个结果数组,数组中的元素是每一个 Promise 对象的返回结果。如果有任何一个 Promise 对象失败了,Promise.all 返回的 Promise 对象的状态变为 rejected 并返回第一个失败的 Promise 对象的错误信息。
Promise.race 方法
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 500, 'Promise 1');
});
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000, 'Promise 2');
});
Promise.race([promise1, promise2]).then(result => {
console.log(result);
});
Promise.race 方法接受一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。当有任何一个 Promise 对象状态变为 fulfilled 或者 rejected,Promise.race 方法就返回的 Promise 对象的状态就会跟随这个 Promise 对象的状态变化。如果第一个 Promise 对象成功执行,Promise.race 返回的 Promise 对象的状态变为 fulfilled 并返回该 Promise 对象的结果,如果第一个 Promise 对象执行失败,Promise.race 返回的 Promise 对象的状态变为 rejected 并返回该 Promise 对象的错误信息。
示例说明
示例1
下面是一个使用 Promise.all 方法的实际例子。假设有一个场景,需要插入一个订单数据到数据库,然后根据订单的邮寄地址发送一封邮件和生成一个 PDF 文件。这些操作都是异步的,我们可以使用 Promise 轻松地编写这个功能。
const insertOrderToDB = orderData => {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('订单数据插入成功');
} else {
reject('订单数据插入失败');
}
}, 500);
});
};
const sendEmail = orderData => {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('邮件发送成功');
} else {
reject('邮件发送失败');
}
}, 500);
});
};
const generatePdf = orderData => {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve('PDF 文件生成成功');
} else {
reject('PDF 文件生成失败');
}
}, 500);
});
};
const orderData = {
orderId: '20210101',
shippingAddress: 'Beijing',
customerName: 'John Doe'
};
Promise.all([insertOrderToDB(orderData), sendEmail(orderData), generatePdf(orderData)])
.then(results => {
console.log('所有操作均已成功:', results);
})
.catch(error => {
console.log('操作失败:', error);
});
上面代码中,我们通过 Promise.all 将订单数据插入到数据库、发送邮件、生成 PDF 文件的操作并行执行,并在所有操作结束后,通过 then 方法处理结果。
示例2
下面是一个使用 Promise.race 方法的实际例子。假设有一个场景,需要调用多个接口查询同一组数据,但是这些接口的响应时间不一样,我们不希望等待时间过长才得到结果,可以使用 Promise.race 方法。
const queryDataFromAPI = url => {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = url === 'api1';
if (success) {
resolve(`来自${url}的数据`);
} else {
reject(`来自${url}的数据查询失败`);
}
}, Math.random() * 1000 + 500);
});
};
const urls = ['api1', 'api2', 'api3'];
Promise.race(urls.map(url => queryDataFromAPI(url)))
.then(result => {
console.log('第一个响应的接口返回的数据:', result);
})
.catch(error => {
console.log('所有接口均未返回数据:', error);
});
上面代码中,我们通过 Promise.race 调用多个接口查询数据,并在第一个接口返回数据后立即停止其它接口的查询,最终得到结果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入学习JavaScript中的promise - Python技术站