MST

星途 面试题库

面试题:JavaScript 函数方法并发使用的优化

现有一组 URL 数组,你需要并发地获取每个 URL 的响应内容(使用 `fetch` 函数,它返回一个 Promise),但由于资源限制,同时并发的请求数不能超过 3 个。请编写一个函数,接收 URL 数组作为参数,返回所有请求成功后的响应数据数组。阐述实现思路以及使用到的函数方法是如何协同工作的。
25.6万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 利用 async/await 来处理异步操作。
  2. 使用队列(queue)来存储所有的 URL。
  3. 用一个计数器(count)来记录当前正在进行的请求数,确保同时并发的请求数不超过 3 个。
  4. 当一个请求完成后,将计数器减 1,并从队列中取出下一个 URL 发起新的请求,直到队列为空。

代码实现

async function fetchUrls(urls) {
    const results = [];
    const queue = [...urls];
    let count = 0;
    const maxConcurrent = 3;

    async function processQueue() {
        while (queue.length > 0 && count < maxConcurrent) {
            count++;
            const url = queue.shift();
            try {
                const response = await fetch(url);
                const data = await response.text();
                results.push(data);
            } catch (error) {
                results.push(error);
            } finally {
                count--;
                if (queue.length > 0) {
                    processQueue();
                }
            }
        }
    }

    await processQueue();
    return results;
}

函数方法协同工作

  1. fetch:用于发起 HTTP 请求并返回一个 Promise,这个 Promise 在请求成功时解析为 Response 对象,失败时被拒绝。
  2. async/awaitasync 函数返回一个 Promiseawait 只能在 async 函数内部使用,它暂停 async 函数的执行,直到其等待的 Promise 被解决(resolved 或 rejected)。在这里,await fetch(url) 等待请求完成,await response.text() 等待将响应内容解析为文本。
  3. 队列操作queue 数组模拟队列,queue.shift() 方法从队列头部取出一个 URL 进行处理。
  4. 计数器操作count 用于记录当前正在进行的请求数,在发起新请求时 count++,请求完成(无论成功或失败)时 count--,以此来控制并发请求数。
  5. 递归调用processQueue 函数在每次请求完成后,检查队列中是否还有 URL,如果有则递归调用自身,发起新的请求,直到队列为空。