Promise 是 JavaScript 中的一种异步编程方式,可以优雅地解决回调地狱问题,提高代码可读性和可维护性,是 JavaScript 开发中必备的技术之一。我将介绍 Promise 的基本原理和用法。
Promise 原理
Promise 本质上是一种对象 - 即异步操作的一个句柄(或占位符),在某个异步操作完成(或失败)之后会被替换成异步操作的结果(或错误)。一个 Promise 的状态只能从初始化为进行中,完成或失败。
Promise 有以下三种状态:
-
Pending: 初始状态,既不是成功,也不是失败状态。
-
Fulfilled: 意味着操作成功完成,Promise 对象传递给 then 方法的回调函数参数是成功完成的结果。
-
Rejected: 意味着操作失败,Promise 对象传递给 then 方法的回调函数参数是失败的原因。
Promise 用法
Promise 用法分为以下两部分: 创建 Promise 和 Promise 的状态修改。
创建 Promise
我们可以使用 Promise 构造函数来创建一个 Promise 对象:
const promise = new Promise((resolve, reject) => {
// 异步操作任务
// 如果成功,则调用 resolve 方法将结果传递出去
// 如果失败,则调用 reject 方法将失败原因传递出去
});
在 Promise 构造函数中,我们执行异步任务,如果成功完成任务,则调用 resolve 方法将结果返回,否则调用 reject 方法将失败原因返回。
Promise 状态修改
我们可以通过 then、catch、finally 等方法来处理 Promise 对象的状态。
-
then: 在 Promise 成功时调用,接收一个处理成功的回调函数。 -
catch: 在 Promise 失败时调用,接收一个处理失败的回调函数。 -
finally: 不管 Promise 成功或失败,都会执行该方法中的任务。
promise
.then(result => {
// 处理 successfulResult
})
.catch(error => {
// 处理 failureReason
})
.finally(() => {
// 无论成功或失败都会执行的逻辑
});
以上方法都是可以链式调用的。例如,我们可以使用 then 方法获取 Promise 对象的成功处理结果,然后再使用 catch 方法处理失败情况:
promise
.then(result => {
// 处理 successfulResult
})
.catch(error => {
// 处理 failureReason
});
Promise 示例
我们来通过一个示例代码来深入理解 Promise 的用法。
假设我们有一个异步获取用户信息的方法 getUserInfo,我们可以通过 Promise 来实现异步调用:
function getUserInfo(userId) {
return new Promise((resolve, reject) => {
// 异步获取用户信息
setTimeout(() => {
const users = {
1: { name: 'Alice' },
2: { name: 'Bob' }
};
const user = users[userId];
if (user) {
resolve(user);
} else {
reject(`User with ID ${userId} not found`);
}
}, 1000);
});
}
在上述代码中,getUserInfo 方法通过 Promise 包装了异步任务,具体实现如下所示:
-
如果找到了对应用户,调用
resolve并传递用户信息。 -
如果没找到,调用
reject并传递错误信息。
接着,我们可以在 vue 组件中使用该方法来展示用户信息:
<template>
<div>
<label>User ID:</label>
<input type="text" v-model="userId">
<button @click="getUser">Get User</button>
<div v-if="user">
<h1>Hello, {{ user.name }}!</h1>
</div>
<div v-else-if="isLoading">Loading...</div>
<div v-else>
<p>User not found!</p>
</div>
</div>
</template>
我认为的关键点是:
-
三个状态 pending fulfilled rejected pending 等待中, 默认创建出来的状态 fulfilled 已完成 rejected 失败
-
回调中接收两个方法 resolve reject 调用resolve方法, 将promise状态从pending改成fulfilled, 将来执行.then resolve(xxx)
调用reject方法, 将promise状态从pending改成rejected, 将来执行.catch reject(xxx)
-
能够使用 promise 对异步操作进行包装 (懂promise的语法)
-
const p = new Promise((resolve, reject) => { // 异步操作 // 异步操作成功 resolve(值) // 异步操作失败 reject(值) }) p.then(xxx => {}).catch(xxx => {}) const res = await p