MST

星途 面试题库

面试题:JavaScript异步编程中的并发与竞争

假设有多个异步任务(可以用setTimeout模拟),这些任务会返回不同的数据。请实现两种场景:1. 并发执行这些任务,当所有任务都完成后,汇总它们的结果并输出。2. 同时发起这些任务,只要有一个任务完成,就立即输出该任务的结果,忽略其他未完成的任务。请分别用Promise.all和Promise.race来实现,并阐述这两个方法在这种场景下的原理和适用场景。
41.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

并发执行任务并汇总结果(Promise.all实现)

// 模拟异步任务
function asyncTask1() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务1的结果');
        }, 1000);
    });
}

function asyncTask2() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务2的结果');
        }, 1500);
    });
}

function asyncTask3() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务3的结果');
        }, 2000);
    });
}

// 使用Promise.all并发执行任务并汇总结果
Promise.all([asyncTask1(), asyncTask2(), asyncTask3()])
  .then((results) => {
        console.log('所有任务完成,汇总结果:', results);
    })
  .catch((error) => {
        console.error('有任务失败:', error);
    });

原理:Promise.all 接收一个 Promise 数组作为参数,它会并发执行这些 Promise。只有当数组里所有的 Promise 都变为 resolved 状态时,Promise.all 才会 resolve,并且将所有 Promise 的 resolved 值组成一个数组作为结果返回。如果其中任何一个 Promise 被 reject,Promise.all 将会立即 reject,并返回该 Promise 的 reject 原因。

适用场景:当需要等待多个异步操作全部完成后再进行下一步处理时,比如同时发起多个 API 请求,在所有请求都返回后进行数据整合和展示。

只要有一个任务完成就输出结果(Promise.race实现)

// 模拟异步任务
function asyncTaskA() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务A的结果');
        }, 1500);
    });
}

function asyncTaskB() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务B的结果');
        }, 1000);
    });
}

function asyncTaskC() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve('任务C的结果');
        }, 2000);
    });
}

// 使用Promise.race只要有一个任务完成就输出结果
Promise.race([asyncTaskA(), asyncTaskB(), asyncTaskC()])
  .then((result) => {
        console.log('第一个完成的任务结果:', result);
    })
  .catch((error) => {
        console.error('有任务失败:', error);
    });

原理:Promise.race 同样接收一个 Promise 数组作为参数,它会并发执行这些 Promise。只要数组中的任何一个 Promise 率先变为 resolved 或者 rejected 状态,Promise.race 就会以相同的状态 resolve 或者 reject,并返回该 Promise 的 resolved 值或者 reject 原因。

适用场景:当只关心多个异步操作中最先完成的那个结果时,比如在多个相同功能的 API 中,只要有一个 API 成功响应就可以,忽略其他 API 的响应。