🍪🧁🍧

Promise与async await

JavaScript Promise 与 async/await 核心知识点总结

1. Promise 核心概念详解

1.1 三种状态 (Three States)

  • pending: 初始状态
  • fulfilled: 成功状态
  • rejected: 失败状态
  • 特性: 状态一旦从 pending 变为 fulfilledpending 变为 rejected,就不会再改变。

1.2 一个执行器函数 (Executor Function)

  • new Promise((resolve, reject) => { ... }) 时,执行器函数 executor(resolve, reject) 会立即同步执行。
  • resolvereject 是 JavaScript 引擎提供的两个函数,用于改变 Promise 的状态。

1.3 resolvereject 回调

  • resolve(value): 将 Promise 状态从 pending 改为 fulfilled,并将成功的结果 value 传递出去。
  • reject(reason): 将 Promise 状态从 pending 改为 rejected,并将失败的原因 reason 传递出去。
  • 重要特性:
    • Promise 的状态一旦改变,就不能再变。
    • 如果 resolvereject 都被调用(例如,在 executor 函数内部),则以第一次调用为准,后续的调用将被忽略。

1.4 实例方法 (Instance Methods)

  • then(onFulfilled, onRejected):
    • onFulfilled: (可选) Promise 状态变为 fulfilled 时执行的回调。
    • onRejected: (可选) Promise 状态变为 rejected 时执行的回调。
    • 返回一个新的 Promise,可以实现链式调用。
  • catch(onRejected):
    • 相当于 then(null, onRejected)then(undefined, onRejected),用于捕获 rejected 状态。
    • 返回一个新的 Promise。
  • finally(onFinally):
    • 无论 Promise 最终状态是 fulfilled 还是 rejectedonFinally 回调都会执行。
    • 返回一个新的 Promise。

2. executor 同步执行与 Promise 的初始状态

  • new Promise(executor) 时,executor(resolve, reject) 函数会立即同步执行
  • executor 函数内部的 resolvereject 被调用之前,Promise 的初始状态是 pending
  • Promise 最终会变成 fulfilled 还是 rejected,取决于在 executor 函数内部是调用了 resolve(value) 还是 reject(reason)
  • 如果 executor 函数执行完毕,但既没有调用 resolve 也没有调用 reject (例如,它们在一个尚未完成的异步操作中),则 Promise 会一直保持 pending 状态。

3. Promise 与 async/await 的区别与联系

特性 (Feature) Promise async/await
核心概念 表示一个异步操作最终完成或失败及其结果值的对象。 基于 Promise 构建的语法糖,旨在以更同步的方式编写异步代码。
语法形式 使用 .then(), .catch(), .finally() 链式调用。 async 用于声明异步函数 (隐式返回 Promise);await 用于等待 Promise。
代码可读性 多个 .then() 嵌套时,可读性可能下降。 代码结构更接近同步代码,通常更简洁、易于理解和维护。
错误处理 主要通过 .catch() 方法或 .then() 的第二个参数。 可以使用标准的 try...catch 结构,更符合同步代码习惯。
返回值 .then() 等方法返回新的 Promise。 async 函数总是隐式返回一个 Promise。
本质关系 Promise 是异步编程的基础和核心。 async/await 是建立在 Promise 之上的更高阶抽象。

面试核心回答建议:

Promise 是异步编程的基石和核心对象。而 async/await 是建立在 Promise 之上的、旨在简化异步代码写法和提升可读性的语法特性,它让我们能以更像同步代码的方式来组织异步逻辑,并且提供了更自然的错误处理机制,其核心依然是 Promise。

4. async/await 如何实现“链式调用”效果

async/await 本身不使用像 Promise 那样的 .then().then() 显式链式方法,但它通过更直观的方式实现了异步操作的顺序执行数据传递(即 Promise 链式调用的核心目的):

  1. 顺序 await 实现串行执行

    • 在一个 async 函数内部,可以按顺序 await 多个返回 Promise 的异步操作。
    • 每一行 await 都会暂停当前 async 函数的执行,直到它所等待的 Promise 完成,然后才会继续执行下一行代码,自然形成操作的“链条”。
  2. 数据通过变量传递

    • await 表达式会返回 Promise 解析后的值。
    • 可以直接将此值赋给变量,在后续的 await 操作或同步逻辑中使用,比在 .then() 回调中层层传递参数更简洁。

效果对比示例:

  • Promise 的 .then():

    // function asyncOperation1() { /* ... */ }
    // function asyncOperation2(data) { /* ... */ }
    // function asyncOperation3(data) { /* ... */ }
    
    // asyncOperation1()
    //   .then(result1 => {
    //     return asyncOperation2(result1);
    //   })
    //   .then(result2 => {
    //     return asyncOperation3(result2);
    //   })
    //   .then(finalResult => {
    //     console.log("最终结果:", finalResult);
    //   })
    //   .catch(error => {
    //     console.error("错误:", error);
    //   });
    
  • async/await 实现等效逻辑:

    // async function asyncOperation1() { /* ... */ }
    // async function asyncOperation2(data) { /* ... */ }
    // async function asyncOperation3(data) { /* ... */ }
    
    // async function fetchDataChain() {
    //   try {
    //     const result1 = await asyncOperation1();
    //     const result2 = await asyncOperation2(result1);
    //     const finalResult = await asyncOperation3(result2);
    //     console.log("最终结果:", finalResult);
    //   } catch (error) {
    //     console.error("错误:", error);
    //   }
    // }
    // fetchDataChain();
    

async/await 通过其同步化的代码结构,天然支持了异步任务的串行化,使得代码逻辑更清晰。

posted @ 2025-05-14 23:25  不想吃fun  阅读(69)  评论(0)    收藏  举报