⏳ 第十章:异步编程进化史

从回调到 Promise,再到 Async/Await 的演进

10.1 事件循环原理

事件循环是 JavaScript 处理异步操作的核心机制。

宏任务与微任务

任务类型 包含的任务 执行时机
宏任务 setTimeout, setInterval, I/O, DOM 事件 每次事件循环的开始
微任务 Promise.then, MutationObserver, process.nextTick 当前宏任务执行完毕后
// 事件循环示例
console.log('1. 同步任务');

setTimeout(() => {
    console.log('4. 宏任务(setTimeout)');
}, 0);

Promise.resolve().then(() => {
    console.log('3. 微任务(Promise)');
});

console.log('2. 同步任务');

// 输出顺序:1 → 2 → 3 → 4

10.2 Promise 详解

Promise 状态

基本用法

// 创建 Promise
const promise = new Promise((resolve, reject) => {
    // 异步操作
    setTimeout(() => {
        const success = true;
        if (success) {
            resolve('操作成功');
        } else {
            reject('操作失败');
        }
    }, 1000);
});

// 处理 Promise
promise
    .then(result => {
        console.log(result); // 操作成功
    })
    .catch(error => {
        console.log(error); // 操作失败
    })
    .finally(() => {
        console.log('操作完成');
    });

Promise 方法

// Promise.all - 全部完成
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);

Promise.all([promise1, promise2, promise3])
    .then(results => {
        console.log(results); // [1, 2, 3]
    });

// Promise.race - 第一个完成
Promise.race([promise1, promise2, promise3])
    .then(result => {
        console.log(result); // 1
    });

// Promise.any - 第一个成功
Promise.any([promise1, promise2, promise3])
    .then(result => {
        console.log(result); // 1
    });

// ES2025/2026 特性:Promise.try
Promise.try(() => {
    return 42;
}).then(result => {
    console.log(result); // 42
});

10.3 Async/Await 语法糖

基本用法

// Async 函数
async function fetchData() {
    try {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        return data;
    } catch (error) {
        console.error(error);
        throw error;
    }
}

// 调用 Async 函数
fetchData().then(data => {
    console.log(data);
});

错误处理

async function handleErrors() {
    try {
        const result = await fetchData();
        console.log(result);
    } catch (error) {
        console.error('发生错误:', error);
    } finally {
        console.log('操作完成');
    }
}

10.4 ES2026 革命性特性:行内 Await 代码块

行内 Await 代码块允许在非 async 函数中使用 await,彻底解决“async 套娃”问题。
// 传统方式(需要 async 函数)
function traditional() {
    async function inner() {
        const data = await fetchData();
        console.log(data);
    };
    inner();
}

// ES2026 方式(行内 Await)
function modern() {
    await {
        const data = await fetchData();
        console.log(data);
    };
}

// 直接在块级作用域使用
{
    await {
        const response = await fetch('https://api.example.com/data');
        const data = await response.json();
        console.log(data);
    };
}

动手练习

练习 1:事件循环

  1. 创建包含宏任务和微任务的代码
  2. 预测输出顺序
  3. 验证事件循环的执行机制

练习 2:Promise

  1. 创建一个 Promise
  2. 处理成功和失败的情况
  3. 使用 Promise.all, Promise.race 等方法

练习 3:Async/Await

  1. 创建一个 Async 函数
  2. 使用 await 处理异步操作
  3. 添加错误处理

练习 4:行内 Await

  1. 测试 ES2026 的行内 Await 代码块
  2. 比较传统方式和新方式的区别
  3. 实现一个使用行内 Await 的例子