ES6 promise-try-catch-模块化开发

一、Promise:异步编程解决方案

Promise 是 ES6 引入的异步编程规范,主要用于解决 "回调地狱" 问题,让异步代码的逻辑更清晰、更易维护。

1. 核心概念与状态

  • 本质:Promise 是一个构造函数,用于封装异步操作,并可以获取操作的成功 / 失败结果。
  • 三种状态 (状态一旦改变,不可逆):
    • pending:初始状态,异步操作未完成。
    • fulfilled(resolved):异步操作成功,状态从 pending 转为 fulfilled
    • rejected:异步操作失败,状态从 pending 转为 rejected
  • 核心方法
    • 构造函数参数:接收一个函数 (resolve, reject) => {}resolve 用于成功时传递结果,reject 用于失败时传递错误。
    • 实例方法:then() 处理成功结果,catch() 处理失败错误。

2. 基本用法(以 AJAX 请求为例)

javascript

运行

复制代码
// 1. 创建 Promise 实例,封装异步操作(AJAX 请求)
function requestData(url) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: url,
      dataType: "json",
      success: (res) => {
        resolve(res); // 成功:调用 resolve 传递结果
      },
      error: (err) => {
        reject(err); // 失败:调用 reject 传递错误
      }
    });
  });
}

// 2. 调用 Promise,处理结果
requestData("arr.txt")
  .then((res) => {
    console.log("请求成功:", res); // 接收 resolve 传递的结果
  })
  .catch((err) => {
    console.log("请求失败:", err); // 接收 reject 传递的错误
  });

3. 解决回调地狱

传统多层异步嵌套(如 "请求 1 成功后请求 2,请求 2 成功后请求 3")会形成 "回调地狱",Promise 可通过 then() 链式调用解决:

javascript

运行

复制代码
// 链式调用:依次执行 3 个 AJAX 请求
requestData("1.txt")
  .then((res1) => {
    console.log("请求1结果:", res1);
    return requestData("2.txt"); // 返回新的 Promise,进入下一个 then
  })
  .then((res2) => {
    console.log("请求2结果:", res2);
    return requestData("3.txt");
  })
  .then((res3) => {
    console.log("请求3结果:", res3);
  })
  .catch((err) => {
    console.log("任意一步失败:", err); // 捕获所有步骤的错误
  });

4. Promise 静态方法

方法 功能描述
Promise.all([p1, p2, p3]) 接收多个 Promise 实例,所有实例都成功 才返回成功结果数组;任意一个失败则直接返回失败。
Promise.race([p1, p2, p3]) 接收多个 Promise 实例,谁先完成(成功 / 失败) 就返回谁的结果,忽略其他实例。
  • 示例(Promise.all 批量请求):

    javascript

    运行

    复制代码
    // 同时请求 2 个接口,全部成功后处理结果
    Promise.all([
      requestData("1.txt"),
      requestData("2.txt")
    ])
      .then(([res1, res2]) => { // 解构结果数组
        console.log("请求1结果:", res1);
        console.log("请求2结果:", res2);
      })
      .catch((err) => {
        console.log("至少一个请求失败:", err);
      });

5. 关键面试点:Promise 是同步还是异步?

  • 结论 :Promise 构造函数内部的代码是同步执行 的,但 resolve/reject 触发的 then()/catch() 回调是异步执行的(放入微任务队列)。

  • 示例: javascript

    运行

    复制代码
    console.log(1);
    let p = new Promise((resolve) => {
      console.log(2); // 同步执行
      resolve(); // 触发 then 回调(异步)
    });
    p.then(() => {
      console.log(4); // 异步执行(微任务)
    });
    console.log(3); // 同步执行
    // 输出顺序:1 → 2 → 3 → 4

二、try-catch:异常捕获

try-catch 语句用于捕获代码执行中的异常(错误),避免程序因报错而中断,同时可以自定义错误处理逻辑。

1. 基本语法

javascript

运行

复制代码
try {
  // 可能出错的代码(尝试执行)
  let data = '{"name":"XX";"age":100}'; // 格式错误的 JSON
  let newData = JSON.parse(data); // 此处会报错
  console.log(newData.name);
} catch (error) {
  // 捕获到错误时执行(error 是错误信息对象)
  console.log("执行出错:", error.message); // 输出:Unexpected token ; in JSON at position 10
} finally {
  // 无论是否出错,都会执行(可选,常用于清理资源)
  console.log("无论对错,我都会执行");
}

2. 注意事项

  • 性能问题try-catch 会轻微影响代码执行效率,避免在高频执行的逻辑(如循环)中使用。

  • 异步错误捕获限制try-catch 无法捕获异步操作(如 setTimeout、AJAX)中的错误,需在异步回调内部单独捕获。

    javascript

    运行

    复制代码
    // 错误示例:无法捕获 setTimeout 内的错误
    try {
      setTimeout(() => {
        console.log(a); // a 未定义,会报错,但 try-catch 捕获不到
      }, 100);
    } catch (err) {
      console.log("捕获不到错误:", err);
    }
    
    // 正确示例:在异步内部捕获
    setTimeout(() => {
      try {
        console.log(a);
      } catch (err) {
        console.log("捕获到错误:", err);
      }
    }, 100);

三、ES6 模块化开发

模块化是将代码拆分为独立文件(模块),通过 export(导出)和 import(导入)实现模块间的依赖管理,解决全局变量污染、代码复用等问题。

1. 核心语法

(1)导出模块(export

在模块文件(如 utils.js)中,通过 export 暴露需要对外提供的变量、函数或对象:

javascript

运行

复制代码
// utils.js
let PI = 3.14;
function sum(a, b) {
  return a + b;
}
const user = { name: "Alice", age: 20 };

// 方式1:按需导出(可导出多个)
export { PI, sum, user };

// 方式2:默认导出(只能有一个默认导出,导入时可自定义名称)
export default function multiply(a, b) {
  return a * b;
}
(2)导入模块(import

在使用模块的文件中,通过 import 引入其他模块的内容,需在 <script> 标签中添加 type="module"

html

预览

复制代码
<!-- index.html -->
<script type="module">
  // 1. 导入按需导出的内容(名称必须与导出一致)
  import { PI, sum, user } from "./utils.js";
  console.log(PI); // 3.14
  console.log(sum(1, 2)); // 3

  // 2. 导入默认导出的内容(可自定义名称,如 "mult")
  import mult from "./utils.js";
  console.log(mult(2, 3)); // 6

  // 3. 批量导入(给模块起别名 "utils")
  import * as utils from "./utils.js";
  console.log(utils.PI); // 3.14
  console.log(utils.sum(3, 4)); // 7
</script>

2. 注意事项

  • 模块文件路径必须完整(如 ./utils.js,不能省略 .js)。
  • 模块内的变量、函数默认是局部的,只有通过 export 导出后才能被其他模块访问。
  • 浏览器环境中,模块脚本会自动开启严格模式(use strict)。

四、async/await:异步代码的 "语法糖"

async/await 是 ES2017(ES8)引入的语法,基于 Promise 实现,让异步代码的写法更接近同步代码,进一步简化异步逻辑。

1. 核心语法

  • async 函数
    • async 修饰的函数,返回值会自动封装为 Promise 对象(若返回普通值,等同于 return Promise.resolve(普通值))。
    • 内部可使用 await 关键字。
  • await 关键字
    • 只能在 async 函数内部使用,用于 "等待" Promise 对象的结果(成功 / 失败)。
    • 等待期间会暂停 async 函数的执行,但不会阻塞整个线程(底层是 Promise 的微任务)。

2. 基本用法(以 AJAX 请求为例)

javascript

运行

复制代码
// 1. 复用之前的 Promise 异步函数
function requestData(url) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: url,
      dataType: "json",
      success: (res) => resolve(res),
      error: (err) => reject(err)
    });
  });
}

// 2. 用 async/await 编写异步逻辑
async function getData() {
  try {
    // 等待 Promise 成功,直接获取结果(无需 then)
    let res1 = await requestData("1.txt");
    console.log("请求1结果:", res1);

    let res2 = await requestData("2.txt");
    console.log("请求2结果:", res2);

    return "所有请求完成";
  } catch (err) {
    // 捕获所有 await 中的错误(等同于 Promise 的 catch)
    console.log("请求失败:", err);
  }
}

// 3. 调用 async 函数(返回 Promise,可加 then 处理)
getData().then((msg) => {
  console.log(msg); // 所有请求完成
});

3. 优势与注意事项

  • 优势 :逻辑清晰,避免 then 链式调用的嵌套,代码可读性更高。
  • 注意事项
    • await 只能等待 Promise 对象,若等待普通值,会直接返回该值(无等待效果)。
    • async 函数内部的错误需用 try-catch 捕获(否则会导致 Promise 变为 rejected 状态,需用 catch 处理)。
    • 若需并行执行多个异步操作,仍需使用 Promise.allawait 默认是串行执行)。
相关推荐
xiangxiongfly9156 小时前
Android 自定义View之BubbleImageView
android·气泡·bubbleimageview·气泡imageview
vivo高启强6 小时前
R8 如何优化我们的代码(2) -- 空值数据流分析
android
2501_916013746 小时前
iOS 26 系统电耗分析实战指南 如何检测电池掉电、液体玻璃导致的能耗变化
android·macos·ios·小程序·uni-app·cocoa·iphone
2501_915921436 小时前
iOS 原生开发全流程解析,iOS 应用开发步骤、Xcode 开发环境配置、ipa 文件打包上传与 App Store 上架实战经验
android·macos·ios·小程序·uni-app·iphone·xcode
低调小一6 小时前
双端 FPS 全景解析:Android 与 iOS 的渲染机制、监控与优化
android·ios·kotlin·swift·fps
如此风景6 小时前
Compose UI中padding操作符顺序对布局的影响
android
vivo高启强7 小时前
R8 如何优化我们的代码(3) -- 值假设与常量
android
00后程序员张7 小时前
iOS 26 帧率测试实战指南,Liquid Glass 动画性能、滚动滑动帧率对比、旧机型流畅性与 uni-app 优化策略
android·ios·小程序·uni-app·cocoa·iphone·webview
新青年.8 小时前
【Android】解决安卓在隐藏系统栏后usb鼠标被隐藏的问题
android