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 默认是串行执行)。
相关推荐
双桥wow5 分钟前
Android Framework开机动画开发
android
fanged7 小时前
天马G前端的使用
android·游戏
一壶浊酒..10 小时前
ajax局部更新
前端·ajax·okhttp
molong93111 小时前
Kotlin 内联函数、高阶函数、扩展函数
android·开发语言·kotlin
叶辞树12 小时前
Android framework调试和AMS等服务调试
android
慕伏白14 小时前
【慕伏白】Android Studio 无线调试配置
android·ide·android studio
低调小一15 小时前
Kuikly 小白拆解系列 · 第1篇|两棵树直调(Kotlin 构建与原生承载)
android·开发语言·kotlin
跟着珅聪学java15 小时前
spring boot 整合 activiti 教程
android·java·spring
川石课堂软件测试16 小时前
全链路Controller压测负载均衡
android·运维·开发语言·python·mysql·adb·负载均衡
2501_9159214317 小时前
iOS 26 电耗监测与优化,耗电问题实战 + 多工具 辅助策略
android·macos·ios·小程序·uni-app·cocoa·iphone