MST

星途 面试题库

面试题:JavaScript 中 Node 异步实现的优化及错误处理

假设你在 Node.js 中使用异步函数读取多个文件并处理其内容,如何使用 Promise 或 async/await 优化这个过程,并有效处理可能出现的错误。请详细说明实现思路并给出代码示例。
11.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 使用 fs/promises:Node.js 提供了 fs/promises 模块,它将文件系统操作封装为返回 Promise 的函数,比传统的回调式 fs 模块更适合异步处理。
  2. Promise.allasync/await
    • Promise.all:可以并行处理多个文件读取操作。它接受一个 Promise 数组,当所有 Promise 都解决(resolved)时,返回一个新的已解决的 Promise,其结果是所有输入 Promise 结果的数组。如果任何一个 Promise 被拒绝(rejected),Promise.all 会立即被拒绝,并将该拒绝原因作为自己的拒绝原因。
    • async/await:它基于 Promise 构建,提供了更简洁的语法来处理异步操作。await 只能在 async 函数内部使用,它会暂停函数执行,直到 await 后的 Promise 被解决或被拒绝。通过 try - catch 块可以捕获并处理异步操作中抛出的错误。

代码示例

const fs = require('fs/promises');

// 使用 Promise.all
async function readFilesWithPromiseAll(files) {
    try {
        const contents = await Promise.all(files.map(file => fs.readFile(file, 'utf8')));
        // 在这里处理文件内容
        console.log(contents);
        return contents;
    } catch (error) {
        // 处理错误
        console.error('读取文件时出错:', error);
        throw error;
    }
}

// 使用 async/await 逐个读取文件
async function readFilesOneByOne(files) {
    let allContents = [];
    for (let file of files) {
        try {
            const content = await fs.readFile(file, 'utf8');
            allContents.push(content);
            // 在这里处理单个文件内容
            console.log(content);
        } catch (error) {
            // 处理单个文件读取错误
            console.error(`读取文件 ${file} 时出错:`, error);
            throw error;
        }
    }
    return allContents;
}

// 示例文件列表
const files = ['file1.txt', 'file2.txt', 'file3.txt'];

// 调用函数
readFilesWithPromiseAll(files).catch(console.error);
readFilesOneByOne(files).catch(console.error);

在上述代码中:

  • readFilesWithPromiseAll 函数使用 Promise.all 并行读取多个文件,适合文件之间无依赖关系的场景,如果有一个文件读取失败,整个操作失败。
  • readFilesOneByOne 函数使用 async/await 逐个读取文件,这样如果一个文件读取失败,后续文件不会再读取,更适合文件读取有顺序依赖或者希望对每个文件的读取错误分别处理的场景。每个函数都通过 try - catch 块来捕获并处理可能出现的文件读取错误。