Promise、Generator、async/await、axios、Ajax、Fetch 啥是啥?

202 阅读5分钟

1. Promise(承诺对象)

  • 定义
    Promise 是 ES6 引入的 JavaScript 标准对象,用于表示一个异步操作的最终完成(或失败)及其结果。它通过 then() 和 catch() 方法处理成功或失败的状态。

  • 核心特性

    • 状态管理:有三种状态:

      • pending(进行中):初始状态。
      • fulfilled(已成功):异步操作成功完成。
      • rejected(已失败):异步操作失败。
    • 链式调用:通过 .then() 链式处理多个异步操作,避免“回调地狱”。

    • 错误处理:通过 .catch() 捕获错误。

  • 使用示例

    javascript
    深色版本
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => resolve("成功"), 1000);
    });
    promise
      .then((result) => console.log(result)) // 输出:成功
      .catch((error) => console.error(error));
    

2. Generator(生成器函数)

  • 定义
    Generator 是 ES6 引入的特殊函数(用 function* 定义),通过 yield 关键字暂停和恢复函数执行。它本身不处理异步,但可通过库(如 co)与 Promise 结合实现异步流程控制。

  • 核心特性

    • 暂停执行yield 可暂停函数,等待外部调用 next() 继续执行。
    • 状态保存:函数内部状态(如变量)在暂停后会被保留。
  • 与异步结合
    需配合 next() 手动控制流程,例如:

    javascript
    深色版本
    function* asyncGenerator() {
      const val1 = yield Promise.resolve(1);
      const val2 = yield Promise.resolve(2);
      return val1 + val2;
    }
    // 需要外部库(如 co)驱动执行
    co(asyncGenerator()).then(result => console.log(result)); // 输出:3
    

3. async/await(异步/等待语法糖)

  • 定义
    ES7 引入的语法糖,基于 Promise,让异步代码看起来更像同步代码。async 声明函数返回一个 Promise,await 暂停函数执行,等待 Promise 结果。

  • 核心特性

    • 同步风格:通过 await 暂停异步操作,代码可读性更高。
    • 错误处理:通过 try/catch 捕获错误,类似同步代码。
  • 与 Promise 的关系

    • async 函数返回一个 Promise。
    • await 只能用于 async 函数内部,等待 Promise 的 resolve 值。
  • 使用示例

    javascript
    深色版本
    async function fetchData() {
      try {
        const response = await fetch("/api/data");
        const data = await response.json();
        console.log(data);
      } catch (error) {
        console.error("请求失败", error);
      }
    }
    

4. axios(基于 Promise 的 HTTP 客户端)

  • 定义
    Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

  • 特性

    • 从浏览器创建 XMLHttpRequests

    • 从 node.js 创建 http 请求

    • 支持 Promise API

    • 拦截请求和响应

    • 转换请求和响应数据

    • 取消请求

    • 超时处理

    • 查询参数序列化支持嵌套项处理

    • 自动将请求体序列化为:

      • JSON (application/json)
      • Multipart / FormData (multipart/form-data)
      • URL encoded form (application/x-www-form-urlencoded)
    • 将 HTML Form 转换成 JSON 进行请求

    • 自动转换JSON数据

    • 获取浏览器和 node.js 的请求进度,并提供额外的信息(速度、剩余时间)

    • 为 node.js 设置带宽限制

    • 兼容符合规范的 FormData 和 Blob(包括 node.js)

    • 客户端支持防御XSRF

  • 使用示例

    javascript
    深色版本
    axios.get("/api/data")
      .then(response => console.log(response.data))
      .catch(error => console.error(error));
    
    // 使用 async/await
    async function getData() {
      const response = await axios.get("/api/data");
      console.log(response.data);
    }
    

5. Ajax(Asynchronous JavaScript and XML)

  • 定义
    Ajax 是一种通过 JavaScript 实现异步网页更新的技术,核心是使用 XMLHttpRequest 对象(或 Fetch API)与服务器通信,无需刷新页面。

  • 核心特性

    • 异步通信:在后台与服务器交换数据,不阻塞用户操作。

    • 数据格式:早期使用 XML,但现代常用 JSON。

    • 实现方式

      • 传统方式:通过 XMLHttpRequest(如知识库中的示例)。
      • 现代方式:通过 Fetch API 或 axios 等库。
  • 示例(传统 XMLHttpRequest)

    javascript
    深色版本
    const xhr = new XMLHttpRequest();
    xhr.open("GET", "/api/data");
    xhr.onload = function () {
      if (xhr.status === 200) {
        console.log(JSON.parse(xhr.responseText));
      }
    };
    xhr.send();
    

6. Fetch(浏览器原生的 HTTP API)

  • 定义
    Fetch 是浏览器原生提供的 API,用于发起 HTTP 请求,返回一个 Promise,支持 async/await

  • 核心特性

    • 基于 Promise:直接返回 Promise,无需第三方库。
    • 灵活配置:支持请求方法、头部、Body 等。
    • 默认不自动解析 JSON:需手动调用 .json()
  • 使用示例

    javascript
    深色版本
    fetch("/api/data")
      .then(response => response.json())
      .then(data => console.log(data));
    
    // 使用 async/await
    async function fetchData() {
      const response = await fetch("/api/data");
      const data = await response.json();
      console.log(data);
    }
    

关系与技术演进

  1. 回调 → Promise → async/await

    • 回调地狱:嵌套回调难以维护。
    • Promise:链式调用解决部分问题,但代码仍显繁琐。
    • async/await:语法糖让异步代码更易读,成为现代标准。
  2. Generator 的角色

    • 是早期尝试,通过 yield 暂停执行,需配合库(如 co)与 Promise 结合。
    • 现代开发中已被 async/await 取代。
  3. HTTP 请求工具

    • Ajax:传统技术,基于 XMLHttpRequest
    • Fetch:现代浏览器原生 API,基于 Promise。
    • axios:第三方库,封装了 Fetch/XMLHttpRequest,提供更友好的 API。

总结对比表

技术核心用途是否基于 Promise现代使用场景
Promise异步操作状态管理作为底层基础,较少直接使用
Generator暂停/恢复函数执行需配合库(如 co)几乎被淘汰,仅特殊场景使用
async/await简化异步代码,同步风格是(基于 Promise)现代异步编程首选
axiosHTTP 请求客户端前端/Node.js 网络请求首选
Ajax异步网页更新(传统)否(基于 XMLHttpRequest)逐渐被 Fetch/axios 替代
Fetch浏览器原生 HTTP API现代浏览器 HTTP 请求标准

关键关系图

深色版本
回调 → AjaxXMLHttpRequest) → PromiseGenerator(配合 Promise) → async/await  
               ↓  
               axios(基于 PromiseHTTP 客户端)  
               ↓  
               Fetch(浏览器原生基于 PromiseAPI

推荐实践

  • 异步控制:优先使用 async/await 替代 Promise 链式调用。
  • HTTP 请求:使用 axios 或 Fetch API,结合 async/await
  • Generator:仅在需要精确控制流程的特殊场景使用(如旧项目维护)。