Promise
promise 基础语法
Promise 是 JavaScript 中处理异步操作的一种方式。它代表了一个异步操作的最终完成或失败,并且其返回值可用于进一步处理
创建一个promise对象
1
2
3
4
5
6
7
8
9
10
11// 创建一个 Promise
const myPromise = new Promise((resolve, reject) => {
// 异步操作,比如一个网络请求
const success = true;
if (success) {
resolve('成功!'); // 如果操作成功,调用 resolve 并传递结果
} else {
reject('失败!'); // 如果操作失败,调用 reject 并传递错误信息
}
});使用一个promise对象
1
2
3
4
5
6// 使用 Promise
myPromise.then((result) => {
console.log(result); // 在操作成功时执行
}).catch((error) => {
console.log(error); // 在操作失败时执行
});
promise三个状态
- Pending(进行中):初始状态,表示异步操作正在进行中
- Fulfilled(已成功):调用resolve函数,表示异步操作已经成功完成,并且返回了一个值。将会调用 then() 方法绑定的回调函数来处理结果。
- Rejected(已失败):调用reject函数,表示异步操作失败了,并返回了一个错误信息。将会调用 catch() 方法绑定的回调函数来处理错误。
当 Promise 的状态从 Pending 转变为 Fulfilled 或 Rejected 时,它就永远不会再改变。这个特性使得我们可以更好地管理和处理异步代码。
在 Promise 对象被创建时,它的初始状态是 pending。随后,通过调用 resolve() 方法可以将其状态转换为 fulfilled,表示异步操作成功完成,并传递一个值作为结果;而调用 reject() 方法则会将其状态转换为 rejected,表示异步操作发生错误或失败,并传递一个原因作为错误信息。
一旦 Promise 的状态发生变化(从 pending 转变到 fulfilled 或 rejected),则其状态不能再次改变。这是 Promise 的重要特性之一。当 Promise 处于 fulfilled 状态时,它会执行与之关联的 then() 回调函数;当处于 rejected 状态时,则会执行与之关联的 catch() 回调函数。
Promise 是一个构造函数 (类)
其实现类似于这样
1 | class MyPromise { |
状态转换
当执行 resolve
方法时,Promise 的状态会由 pending
转换为 fulfilled
,并且将成功的数据存储在 value
属性中。
当执行 reject
方法时,Promise 的状态会由 pending
转换为 rejected
,并且将错误信息存储在 value
属性中。
then() 和 catch() 方法
Promise 实例具有 then() 和 catch() 方法,在异步操作完成后可以通过这些方法注册回调来处理结果或错误。
1 | let promise = new Promise((resolve, reject) => { |
链式调用
then() 方法返回一个新的 Promise 对象,因此可以进行链式调用(chaining)来处理多个异步操作。
1 | let promise1 = new Promise((resolve, reject) => setTimeout(resolve(1),1000)); |
异步操作管理
异步任务发起后可立即返回一个 pending 状态的 promise 对象,并将 resolve 或者 reject 操作交给内部任务控制。
总结来说,Promise 是通过构造函数创建出来的对象,在内部管理着自身状态和值,在外部提供了方法以及接口供用户使用。其设计使得代码更加清晰易读、避免了“回调地狱”,并方便了对异步任务流程控制
then 处理
then() 方法用于注册回调函数来处理异步操作的结果或错误。then() 方法接受两个参数:onFulfilled 和 onRejected,分别代表在异步操作成功和失败时要执行的回调函数。
1 | promise.then(onFulfilled, onRejected) |
以下是使用 then() 方法处理异步操作结果和错误的示例代码:
1 | let promise = new Promise((resolve, reject) => { |
catch 处理
p.then(inFulFilled, onRejected).then(inFulFilled, onRejected).catch()
catch可以全局捕获,即可以捕获前面所有then() 的错误
p.then(onFulfilled, onRejected)
p
是一个 Promise 对象,通过调用then()
方法来注册在 Promise 完成(fulfilled)或拒绝(rejected)时要执行的回调函数。onFulfilled
是一个可选参数,表示在 Promise 由 pending 转变为 fulfilled 时要执行的回调函数。onRejected
也是一个可选参数,表示在 Promise 由 pending 转变为 rejected 时要执行的回调函数。- 当 Promise 状态变为 fulfilled 时,会执行
onFulfilled
回调函数;当状态变为 rejected 时,会执行onRejected
回调函数。
.catch()
catch()
方法是Promise
原型对象上的方法,用于捕获前面任何一个 Promise 链中产生的错误,即全局捕获
链式调用
fetchData()
返回一个 Promise,然后通过 .then()
方法链式调用处理数据。每个 .then()
都接收前一个 Promise 返回的结果,并返回一个新的 Promise,从而形成链式调用。如果任何一个 .then()
中出现了错误,可以通过 .catch()
捕获并处理。
1 |
|
resolve
Promise.resolve()
是一个静态方法,用于返回一个已解决的 Promise 对象。这个方法通常用于将非 Promise 值包装为一个 Promise,或者将一个已经解决的 Promise 再次返回。
- 包装非 Promise 值:如果传入一个普通的值(例如,数字、字符串等),
Promise.resolve(value)
会返回一个以该值为结果成功的 Promise。 - 返回已解决的 Promise:如果传入一个已解决的 Promise,它会直接返回这个 Promise,而不进行任何处理。
- 即使是 Promise 也会进行处理:即使传入的值是一个 Promise,该 Promise 的状态与
Promise.resolve
返回的 Promise 的状态是相同的。
普通用法
1 | const promise1 = Promise.resolve(42); |
已解决的Promise
1 | const existingPromise = Promise.resolve('Already resolved'); |
异步操作
1 | //当传入的值是一个 Promise 时,Promise.resolve 不会返回新的 Promise,而是直接返回原 Promise |
Promise 链接
1 | //Promise.resolve() 也常用于 Promise 链中,以确保获得一个 Promise |
reject
用于返回一个带有拒绝状态的 Promise 对象。当调用 Promise.reject()
时,返回的 Promise 对象将以指定的原因(reason)被拒绝。
- 参数:
Promise.reject()
方法接收一个参数作为 Promise 被拒绝的原因(reason)。这个参数可以是任何值,通常是一个 Error 对象或一个字符串,用于描述拒绝的原因。 - 返回值:
Promise.reject()
返回一个带有拒绝状态的 Promise 对象,该对象的状态为 rejected,并且 rejection 值即为传入的原因参数。 - 使用场景:
- 当需要显式地创建一个被拒绝的 Promise 对象时,可以使用
Promise.reject()
。 - 可以在异步操作中模拟出现错误或异常情况,使得 Promise 进入 rejected 状态。
- 通常与
.catch()
或Promise.catch()
一起使用,用于捕获并处理 Promise 链中的错误。
- 当需要显式地创建一个被拒绝的 Promise 对象时,可以使用
1 | // 假设有一个返回 Promise 的函数 fetchData 和对返回数据进行处理的函数 processData |
race
接收一个包含多个 Promise 对象的可迭代对象(比如数组),并返回一个新的 Promise。这个新的 Promise 将在第一个传入的 Promise 对象状态发生改变时,采用第一个发生改变的状态,并以此状态进行后续操作。
- 参数:
Promise.race()
方法接收一个可迭代对象作为参数,通常是包含多个 Promise 对象的数组。如果传入非可迭代对象,则会导致 TypeError。 - 返回值:
Promise.race()
返回一个全新的 Promise 实例。当传入的多个 Promises 中有任意一个完成(无论是 resolve 还是 reject),返回的新 Promise 就会采用该完成状态,并且其后续操作也将以此为基础。 - 使用场景:
- 在多个异步任务中,只要有其中之一完成就能得到结果时,可以使用
Promise.race()
。 - 可以设置超时机制,在一定时间内没有得到结果就放弃等待。
- 针对某些情况下需要快速响应或者处理优先级问题。
- 在多个异步任务中,只要有其中之一完成就能得到结果时,可以使用
1 | const promise1 = new Promise((resolve, reject) => { |
all
用于将多个 Promise 实例包装成一个新的 Promise 实例。当传入的所有 Promise 都变为 resolved 状态时,Promise.all()
返回的 Promise 才会变为 resolved 状态;如果其中任何一个 Promise 变为 rejected 状态,则整个 Promise.all()
返回的 Promise 也会立即变为 rejected 状态。
- 参数:
Promise.all()
方法接收一个可迭代对象作为参数,通常是包含多个 Promise 对象的数组。如果传入非可迭代对象,则会导致 TypeError。 - 返回值:
Promise.all()
返回一个全新的 Promise 实例。当传入的所有 Promises 都成功完成时,返回的新 Promise 将以包含所有结果值的数组进行 resolve;如果任一 Promise 失败,则返回的 Promise 将以失败原因进行 reject。 - 使用场景:
- 当需要等待多个异步操作都完成后才执行后续操作时,可以使用
Promise.all()
。 - 用于并行执行多个异步任务,提高效率。
- 可以将多个独立的异步任务组合成一个整体,便于管理和控制。
- 当需要等待多个异步操作都完成后才执行后续操作时,可以使用
1 | const promise1 = new Promise((resolve, reject) => { |
手写promise
1 | // 定义一个名为 MyPromise 的构造函数 |
其他处理异步的方法
处理异步操作是 JavaScript 中常见的任务。有几种方法可以处理异步操作,包括使用回调函数、Promise、async/await 和事件监听器等。
- 回调函数:回调函数是一种传递给异步函数的函数,用于在异步操作完成后执行。回调函数通常作为异步函数的最后一个参数传递,并在操作完成时被调用。这种方式可以处理简单的异步操作,但当有多个异步操作需要处理时,回调函数嵌套会导致回调地狱,使代码难以理解和维护。
- Promise:Promise 是一种用于处理异步操作的对象。它表示一个异步操作的最终完成或失败,并提供了链式调用的方式来处理操作结果。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。通过使用 Promise,可以更好地组织和管理异步代码,避免回调地狱的问题。
- async/await:async/await 是 ECMAScript 2017 引入的异步编程模型。它基于 Promise,并提供了一种更简洁的语法来处理异步操作。通过在函数前面添加 async 关键字,可以将函数声明为异步函数。在异步函数内部,可以使用 await 关键字来等待一个 Promise 对象的解决,并以同步的方式获取操作结果。这种方式使得异步代码看起来更像是同步代码,更易于理解和编写。
- 事件监听器:某些异步操作可能会触发事件,可以使用事件监听器来处理这些事件。通过注册事件监听器,可以在异步操作完成时执行相应的回调函数。这种方式常用于处理浏览器中的事件,如点击事件、加载事件等。