MST

星途 面试题库

面试题:Node.js异步编程在高并发API调用项目中的优化

假设你正在开发一个Node.js应用,需要同时调用多个第三方API获取数据,每个API调用的响应时间不同,并且可能会出现网络延迟或错误。请阐述如何使用异步编程技术(如Promise.allSettled、队列控制等)对这些API调用进行优化,以确保高效且稳定的数据获取,并分析这样做的优缺点。
42.9万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

使用Promise.allSettled优化API调用

  1. 代码示例
    const axios = require('axios');
    
    const apiCalls = [
        axios.get('https://api.example.com/data1'),
        axios.get('https://api.example.com/data2'),
        axios.get('https://api.example.com/data3')
    ];
    
    Promise.allSettled(apiCalls)
       .then(results => {
            results.forEach((result, index) => {
                if (result.status === 'fulfilled') {
                    console.log(`API ${index + 1}成功:`, result.value.data);
                } else {
                    console.log(`API ${index + 1}失败:`, result.reason);
                }
            });
        });
    
  2. 原理
    • Promise.allSettled会等待所有传入的Promise对象都被解决(无论是成功还是失败),然后返回一个新的Promise对象。
    • 这个新的Promise对象的结果是一个数组,数组中的每个元素对应于传入的Promise对象的结果,每个元素是一个对象,有status属性(值为fulfilledrejected),如果statusfulfilled,还有value属性保存成功的值;如果statusrejected,则有reason属性保存失败的原因。

使用队列控制优化API调用

  1. 代码示例
    const axios = require('axios');
    
    const apiQueue = [
        () => axios.get('https://api.example.com/data1'),
        () => axios.get('https://api.example.com/data2'),
        () => axios.get('https://api.example.com/data3')
    ];
    
    function processQueue(queue) {
        let index = 0;
        return new Promise((resolve, reject) => {
            function next() {
                if (index >= queue.length) {
                    resolve();
                    return;
                }
                queue[index]()
                   .then(result => {
                        console.log(`API ${index + 1}成功:`, result.data);
                        index++;
                        next();
                    })
                   .catch(error => {
                        console.log(`API ${index + 1}失败:`, error);
                        reject(error);
                    });
            }
            next();
        });
    }
    
    processQueue(apiQueue);
    
  2. 原理
    • 将API调用函数放入一个队列中。
    • 通过processQueue函数,每次只处理队列中的一个API调用,当前一个API调用完成(无论是成功还是失败),再处理下一个。这样可以控制并发量,避免因过多并发请求导致网络拥堵或资源耗尽。

优缺点分析

  1. Promise.allSettled的优点
    • 高效性:所有API调用同时发起,充分利用并行性,能在最短时间内获取所有数据(假设网络资源充足)。
    • 全面反馈:能得到每个API调用的结果,无论是成功还是失败,便于统一处理和分析。
  2. Promise.allSettled的缺点
    • 资源消耗:如果同时发起过多API调用,可能会耗尽网络资源或导致应用程序响应变慢,特别是在网络环境较差时。
    • 错误处理:当其中一个API调用失败时,不会立即停止所有调用,可能会导致不必要的资源浪费在后续可能失败的调用上。
  3. 队列控制的优点
    • 稳定性:通过控制并发量,能有效避免因过多请求导致的网络拥堵和资源耗尽,在网络不稳定或API性能较差时表现更稳定。
    • 错误处理:当某个API调用失败时,可以根据需求选择立即停止后续调用,减少不必要的资源浪费。
  4. 队列控制的缺点
    • 效率问题:由于是顺序执行,整体获取数据的时间可能会比Promise.allSettled长,特别是在API响应时间较长且数量较多的情况下。
    • 复杂度:代码实现相对复杂,需要手动管理队列和控制执行流程。