如果这篇文章对您有益,可以点赞收藏关注哦,谢谢!

目录

1. 回调函数 (Callback)

是什么?

示例:

缺点:

适用场景:

2. Promise

是什么?

示例:

优点:

适用场景:

⭐3. async / await

是什么?

示例:

优点:

适用场景:

4. 三者对比总结

5.进化关系


1. 回调函数 (Callback)

是什么?

  • 最原始的异步处理方式。

  • 把一个函数作为参数传给另一个函数,在异步操作完成时调用它。

  • 核心问题:回调地狱 (Callback Hell)。当多个异步操作需要顺序执行时,代码会层层嵌套,形成可怕的“金字塔形状”,导致代码难以阅读和维护。

示例:

// 模拟网络请求
function getData(callback) {
  setTimeout(() => {
    callback("回调函数返回的数据");
  }, 1000);
}

getData(result => {
  console.log("收到:", result);
});

缺点:

  • 回调地狱:多个异步任务嵌套时,代码层层缩进,很难维护。

doA(function() {
  doB(function() {
    doC(function() {
      // ...
    });
  });
});

适用场景:

  • 早期 JS 异步编程唯一的选择(比如早期的 Ajax、Node.js API)。

2. Promise

是什么?

  • ES6 引入的异步编程解决方案。

  • 它代表一个未来才会返回的结果(成功 resolve / 失败 reject)。

  • 支持 .then 链式调用,避免回调地狱。

  • 核心优势:链式调用 (Chaining)。让异步流程可以像“流水线”一样写下来,而不是向右嵌套。

示例:

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => resolve("Promise 返回的数据"), 1000);
  });
}

getData()
  .then(result => {
    console.log("收到:", result);
    return "下一步数据";
  })
  .then(next => {
    console.log("链式调用:", next);
  })
  .catch(err => console.error("出错:", err));

优点:

  • 解决回调地狱。

  • 错误可以统一 .catch 处理。

  • 多个异步任务并发 / 顺序执行更方便。

适用场景:

  • 网络请求、文件读取等异步逻辑(现代前端项目都大量用)。

运用场景:

  1. 所有现代的异步 Web API(如 fetch())。

  2. 任何需要顺序执行多个异步操作的场景。

  3. 需要更好地集中处理错误的场景。

  4. async/await 的底层基础

⭐3. async / await

是什么?

  • ES2017(ES8)引入的语法糖。它的底层依然是 Promise,但通过 async 和 await 这两个关键字,让你能够用写同步代码的方式来写异步代码。这是目前最简洁、最易读的方式。

  • 基于 Promise 实现,本质不是新的东西,而是让写法更直观。

  • await 等待 Promise 的结果,代码结构像同步。

  • 核心优势:同步代码的外貌,异步代码的心。 彻底消除了“回调”和“链式调用”的痕迹,代码逻辑变得一目了然。

示例:

function getData() {
  return new Promise(resolve => {
    setTimeout(() => resolve("async/await 返回的数据"), 1000);
  });
}

async function run() {
  try {
    let result = await getData();
    console.log("收到:", result);

    let next = await Promise.resolve("下一步数据");
    console.log("链式写法更简洁:", next);
  } catch (err) {
    console.error("出错:", err);
  }
}

run();

优点:

  • 代码像同步,逻辑更清晰。

  • then 链式更好读

  • 错误处理更自然(try/catch)。

适用场景:

  • 多个异步任务 顺序依赖 的情况。

  • 现代前端项目推荐使用 async/await

  • 处理任何基于 Promise 的异步操作。这是现代 JavaScript 开发的绝对主流和首选

  • 需要编写复杂异步流程(如循环、条件判断中有异步操作)时,async/await 的优势是毁灭性的。

4. 三者对比总结

一句话总结

  • 回调 → Promise → async/await 是 JS 异步编程的三代进化。

  • 回调 太乱,Promise 解决回调地狱async/await进一步让异步写法和同步一样清晰

特性 回调函数 (Callback) Promise Async/Await
代码风格 横向嵌套,回调地狱 纵向链式,流水线 同步风格,最直观
错误处理 需要在每个回调内部判断 集中处理,一个 .catch() 管全程 集中处理,用 try-catch
可读性 差,逻辑混乱 良好 极佳,逻辑清晰
本质 最基础的原生方式 语法结构,是一个对象 语法糖,底层是 Promise

特点 回调 (Callback) Promise async/await
写法风格 函数套函数(嵌套) 链式调用 像同步代码
错误处理 每层要单独处理 .catch 统一处理 try/catch
可读性 很差(回调地狱) 较好 最佳
本质 传函数执行 封装异步状态 Promise 语法糖
使用年代 早期主流 ES6 普及 ES2017 之后普及

5.进化关系

回调函数 → Promise → Async/Await

这是一个不断抽象和简化的发展过程:

  1. Promise 是对回调模式的革命性改进,它通过链式调用解决了嵌套问题。

  2. Async/Await 是对 Promise 的进一步升华,它隐藏了 Promise 的链式语法,让你专注于业务逻辑本身,实现了“用同步的思想写异步的代码”。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐