关于我 壹文 项目 三五好友
📚 JavaScript 异步编程入门:Promise 与 Async/Await 2024-09-25
文章摘要

📚 JavaScript 异步编程入门:Promise 与 Async/Await

在现代 JavaScript 开发中,异步编程是不可或缺的一部分。本文将为你详细介绍 PromiseAsync/Await,以及它们在处理异步操作中的应用和区别。🚀


🌀 什么是 Promise?

Promise 是 JavaScript 中处理异步操作的一种机制。它代表了一个可能在未来完成或失败的操作,并允许你在操作完成后处理结果或错误。

🔑 Promise 的关键点:

  1. 状态

    • Pending(进行中):初始状态,操作尚未完成。
    • Fulfilled(已完成):操作成功完成。
    • Rejected(已失败):操作失败。
  2. 特性

    • 状态不可变:一旦改变状态,就不会再改变。
    • 回调自动调用:状态改变后,相关回调自动执行。

🌟 使用示例:

// 创建一个新的 Promise
const promise = new Promise((resolve, reject) => {
  // 模拟异步操作
  if (/* 操作成功 */) {
    resolve(value); // 成功时调用 resolve
  } else {
    reject(error); // 失败时调用 reject
  }
});

// 处理 Promise
promise
  .then(value => {
    // 操作成功时执行
  })
  .catch(error => {
    // 操作失败时执行
  });

⚡ Async/Await

Async/Await 是基于 Promise 的语法糖, introduced in ES2017,旨在让异步代码看起来更像同步代码,从而提高可读性和可维护性。

🔑 关键点:

  • async 函数:声明为 async 的函数返回一个 Promise
  • await 关键字:用于等待一个 Promise 解决,并获取其结果。

🌟 使用示例:

async function myAsyncFunction() {
  try {
    const result = await someAsyncOperation(); // 等待异步操作完成
    console.log(result);
  } catch (error) {
    console.error(error); // 捕获错误
  }
}

myAsyncFunction();

🛠️ 适用场景

✅ 适用场景包括:

  • 网络请求:如获取数据、提交表单等。
  • 文件操作:读写文件。
  • 定时器:延迟执行某些操作。

特别适用于需要进行一系列异步操作的场景,例如先从服务器获取数据,再根据数据执行其他操作。🔄


📝 使用技巧

  1. 错误处理
    • 使用 .catch()try/catch 捕获错误,避免未处理的错误。
  2. 链式调用
    • 利用 Promise 的链式特性,保持代码清晰。
  3. 并行执行
    • 使用 Promise.all()Promise.race() 同时处理多个异步操作。
  4. 性能优化
    • 处理大量异步操作时,考虑使用 Web Workersstreams 提高性能。

💡 示例讲解

以下是一个实际的代码示例,展示了如何在 TypeScript 中结合使用 async/await.thentry/catch

📁 src/utils/auth.ts

// src/utils/auth.ts
// 认证相关的辅助函数

import bcrypt from "bcrypt";

// 加载管理员密码
const ADMIN_PASSWORD_HASH = process.env.ADMIN_PASSWORD_HASH || "";

/**
 * 验证管理员密码
 * @param password 明文密码
 * @returns 是否验证成功
 */
export async function verifyPassword(password: string): Promise<boolean> {
  return bcrypt.compare(password, ADMIN_PASSWORD_HASH);
}

/**
 * 设置管理员密码(用于生成 ADMIN_PASSWORD_HASH)
 * @param password 明文密码
 * @returns 哈希后的密码
 */
export async function hashPassword(password: string): Promise<string> {
  const saltRounds = 10;
  const hash = await bcrypt.hash(password, saltRounds);
  return hash;
}

📄 详细注释的代码案例

// src/utils/auth.ts
// 认证相关的辅助函数

import bcrypt from "bcrypt";

// 从环境变量中加载管理员的密码哈希值
const ADMIN_PASSWORD_HASH = process.env.ADMIN_PASSWORD_HASH || "";

/**
 * 验证管理员密码
 * @param password 明文密码
 * @returns 是否验证成功
 */
export async function verifyPassword(password: string): Promise<boolean> {
  try {
    // 使用 bcrypt.compare 比较明文密码和存储的哈希值
    return await bcrypt.compare(password, ADMIN_PASSWORD_HASH)
      .then(result => {
        return result; // 返回比较结果(布尔值)
      });
  } catch (error) {
    // 捕获并处理可能的错误
    console.error("Password verification failed:", error);
    return false; // 验证失败时返回 false
  }
}

/**
 * 设置管理员密码(用于生成 ADMIN_PASSWORD_HASH)
 * @param password 明文密码
 * @returns 哈希后的密码
 */
export async function hashPassword(password: string): Promise<string> {
  const saltRounds = 10; // 定义盐值轮数,用于增强哈希的安全性
  // 使用 bcrypt.hash 对明文密码进行哈希处理
  const hash = await bcrypt.hash(password, saltRounds);
  return hash; // 返回哈希后的密码
}

📄 同步与异步操作的例子

以下示例展示了在等待异步操作时,其他函数如何继续执行,而不被阻塞。

// src/utils/asyncExample.ts
// 示例文件,展示 async/await 与 Promise 的使用

/**
 * 模拟一个耗时的异步操作,比如网络请求
 * @param delay 延迟时间(毫秒)
 * @returns Promise<void> 在指定延迟后解决
 */
function simulateAsyncOperation(delay: number): Promise<void> {
  return new Promise<void>(resolve => {
    setTimeout(resolve, delay); // 使用 setTimeout 模拟延迟
  });
}

/**
 * Function 1:启动后等待2秒后完成
 */
function function1(): void {
  console.log("Function 1 started");
  simulateAsyncOperation(2000).then(() => {
    console.log("Function 1 completed after 2 seconds");
  });
}

/**
 * Function 2:启动后等待1.5秒后完成
 */
function function2(): void {
  console.log("Function 2 started");
  simulateAsyncOperation(1500).then(() => {
    console.log("Function 2 completed after 1.5 seconds");
  });
}

/**
 * Function 3:异步函数,等待3秒后完成
 */
async function function3(): Promise<void> {
  console.log("Function 3 started");
  try {
    await simulateAsyncOperation(3000); // 等待异步操作完成
    console.log("Function 3 completed after 3 seconds");
  } catch (error) {
    console.error("An error occurred in Function 3:", error);
  }
}

/**
 * Function 4:立即完成,没有异步操作
 */
function function4(): void {
  console.log("Function 4 started");
  console.log("Function 4 completed immediately");
}

/**
 * 主函数:同时调用多个函数,观察执行顺序
 */
function main(): void {
  console.log("Main function started");
  function1();
  function2();
  function3();
  function4();
  console.log("Main function completed");
}

main();

📄 运行结果

Main function started
Function 1 started
Function 2 started
Function 3 started
Function 4 started
Function 4 completed immediately
Function 2 completed after 1.5 seconds
Function 1 completed after 2 seconds
Function 3 completed after 3 seconds
Main function completed

🧩 总结

  • PromiseAsync/Await 是 JavaScript 中处理异步操作的核心工具。它们使代码更加清晰、可读和易于维护。
  • Promise 适用于简单的异步操作和链式调用,而 Async/Await 提供了更直观的异步代码编写方式。
  • 在实际开发中,选择合适的方式处理异步操作,可以显著提高代码质量和开发效率。✨

希望这篇文章能帮助你更好地理解 JavaScript 的异步编程概念,祝你编程愉快!💻🎉

Not-By-AI