MST

星途 面试题库

面试题:JavaScript await 表达式在并发与竞争异步操作场景下的深入理解与应用

在 JavaScript 中,假设有多个异步任务,其中部分任务可以并发执行以提高效率,但最终需要等待所有任务完成后进行统一处理。另外,有一个特殊任务,只要这个任务先完成,就需要立即中断其他正在执行的任务并进行处理。请使用 async/await 结合其他相关特性(如 Promise.all、Promise.race 等)实现这个需求,并详细解释在实现过程中 await 表达式与其他方法是如何协同工作的,以及如何处理可能出现的错误情况。
12.4万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
async function executeTasks() {
    const tasks = [
        () => new Promise((resolve) => setTimeout(() => resolve('Task 1'), 2000)),
        () => new Promise((resolve) => setTimeout(() => resolve('Task 2'), 1000)),
        () => new Promise((resolve) => setTimeout(() => resolve('Task 3'), 3000)),
        () => new Promise((resolve) => setTimeout(() => resolve('Special Task'), 1500))
    ];

    let specialTaskIndex = null;
    for (let i = 0; i < tasks.length; i++) {
        if (tasks[i].name === 'Special Task') {
            specialTaskIndex = i;
            break;
        }
    }

    if (specialTaskIndex === null) {
        throw new Error('Special task not found');
    }

    const specialTaskPromise = tasks[specialTaskIndex]();
    const otherTasksPromises = tasks.filter((_, index) => index!== specialTaskIndex).map(task => task());

    const raceResult = await Promise.race([specialTaskPromise, ...otherTasksPromises]);

    if (raceResult === 'Special Task') {
        // 中断其他任务,这里可以通过设置标志位等方式中断其他任务逻辑
        console.log('Special task completed, interrupting other tasks');
        return;
    }

    try {
        const allResults = await Promise.all(otherTasksPromises);
        console.log('All non - special tasks completed:', allResults);
    } catch (error) {
        console.error('Error in non - special tasks:', error);
    }
}

executeTasks();

代码解释

  1. 任务定义:定义了多个异步任务,其中包含一个特殊任务。
  2. 查找特殊任务:通过遍历任务数组,找到特殊任务的索引位置。
  3. 分离任务:将特殊任务和其他任务分开,分别创建对应的 Promise 数组。
  4. 使用 Promise.raceawait Promise.race([specialTaskPromise, ...otherTasksPromises]) 会等待第一个完成的任务。如果特殊任务先完成,就可以中断其他任务。
  5. 处理特殊任务先完成的情况:如果特殊任务先完成,打印中断信息并返回。
  6. 处理其他任务完成情况:使用 Promise.all 等待所有非特殊任务完成,并处理可能出现的错误。

await 表达式与其他方法的协同工作

  • awaitPromise.raceawait 暂停 async 函数的执行,直到 Promise.race 中某个 Promise 被解决(resolved)或被拒绝(rejected)。这样就可以及时处理先完成的任务,特别是特殊任务。
  • awaitPromise.allawait 等待 Promise.all 中所有的 Promise 都被解决(resolved),如果其中任何一个 Promise 被拒绝(rejected),Promise.all 会立即被拒绝,await 会抛出这个错误,从而可以在 catch 块中处理。

错误处理

  • 查找特殊任务失败:如果没有找到特殊任务,抛出一个错误,在调用 executeTasks 的外层可以捕获处理。
  • 非特殊任务错误Promise.all 中的任务如果有任何一个出现错误,await Promise.all 会抛出错误,通过 try...catch 块捕获并处理这个错误。