这是一个很重要的话题,让我们逐步讲解:

  1. 事件循环基本概念:
// JavaScript执行顺序
console.log('1'); // 同步任务
setTimeout(() => console.log('2'), 0); // 宏任务
Promise.resolve().then(() => console.log('3')); // 微任务
console.log('4');

// 输出顺序:1, 4, 3, 2
  1. 任务队列分类:
// 宏任务(macrotask)
setTimeout
setInterval
setImmediate (Node.js)
requestAnimationFrame
I/O
UI渲染

// 微任务(microtask)
Promise.then/catch/finally
process.nextTick (Node.js)
MutationObserver
  1. Promise的基本使用:
// 基本语法
const promise = new Promise((resolve, reject) => {
    // 异步操作
    if (/* 成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
});

// 链式调用
promise
    .then(value => {
        // 处理成功
    })
    .catch(error => {
        // 处理错误
    })
    .finally(() => {
        // 总是执行
    });

// Promise方法
Promise.all([p1, p2, p3]) // 所有Promise都完成
Promise.race([p1, p2, p3]) // 第一个完成的Promise
Promise.allSettled([p1, p2, p3]) // 所有Promise都结束
Promise.any([p1, p2, p3]) // 第一个成功的Promise
  1. async/await使用:
// 基本语法
async function getData() {
    try {
        const result = await fetchData();
        return result;
    } catch (error) {
        console.error(error);
    }
}

// 并行执行
async function parallel() {
    const [result1, result2] = await Promise.all([
        fetch('url1'),
        fetch('url2')
    ]);
}

// 循环中使用
async function processArray(array) {
    // 串行执行
    for (const item of array) {
        await processItem(item);
    }
    
    // 并行执行
    const promises = array.map(item => processItem(item));
    await Promise.all(promises);
}
  1. 复杂示例:
// 事件循环示例
console.log('1'); // 同步

setTimeout(() => {
    console.log('2'); // 宏任务1
    Promise.resolve().then(() => {
        console.log('3'); // 宏任务1中的微任务
    });
}, 0);

Promise.resolve().then(() => {
    console.log('4'); // 微任务1
    setTimeout(() => {
        console.log('5'); // 微任务1中的宏任务
    }, 0);
});

console.log('6'); // 同步

// 输出:1, 6, 4, 2, 3, 5
  1. 错误处理:
// Promise错误处理
promise
    .then(data => {
        throw new Error('error');
    })
    .catch(error => {
        console.error(error);
        return 'recovered';
    })
    .then(data => {
        console.log(data); // 'recovered'
    });

// async/await错误处理
async function errorHandling() {
    try {
        await Promise.reject('error');
    } catch (error) {
        console.error(error);
    }
}
  1. 实际应用场景:
// 请求重试
async function fetchWithRetry(url, retries = 3) {
    for (let i = 0; i < retries; i++) {
        try {
            return await fetch(url);
        } catch (error) {
            if (i === retries - 1) throw error;
            await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
        }
    }
}

// 并发控制
async function pool(tasks, poolLimit) {
    const results = [];
    const executing = new Set();
    
    for (const task of tasks) {
        const promise = Promise.resolve().then(() => task());
        results.push(promise);
        
        executing.add(promise);
        const clean = () => executing.delete(promise);
        promise.then(clean, clean);
        
        if (executing.size >= poolLimit) {
            await Promise.race(executing);
        }
    }
    
    return Promise.all(results);
}
  1. 常见陷阱:
// Promise.resolve()的陷阱
Promise.resolve(new Promise(resolve => {
    setTimeout(resolve, 1000);
})).then(() => console.log('done'));

// async函数总是返回Promise
async function fn() {
    return 1;
}
console.log(fn()); // Promise {<fulfilled>: 1}

// await的使用位置
function wrong() {
    await fetchData(); // SyntaxError
}
  1. 性能优化:
// 避免不必要的await
async function optimized() {
    const promise1 = fetchData1(); // 不用await
    const promise2 = fetchData2(); // 不用await
    const [data1, data2] = await Promise.all([promise1, promise2]);
}

// 使用Promise.all而不是串行await
async function better() {
    const results = await Promise.all([
        fetch('url1'),
        fetch('url2'),
        fetch('url3')
    ]);
}
  1. 最佳实践:
  • 合理使用Promise.all进行并行操作
  • 正确处理错误情况
  • 避免回调地狱
  • 注意内存泄漏
  • 合理使用async/await
  • 理解事件循环机制
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐