MST

星途 面试题库

面试题:Node.js fs模块异步写入文件在高并发场景下的处理

在一个Node.js应用中,有多个并发请求需要向同一个文件写入数据,使用fs模块的异步写入操作。请设计一个方案来确保数据写入的完整性和顺序性,同时要考虑性能。详细说明设计思路并给出核心代码实现。
36.6万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 队列机制:使用一个队列来存储所有待写入的数据。这样可以保证数据按照接收的顺序排列。
  2. 锁机制:引入一个锁变量,用于标识当前是否有写入操作正在进行。当有写入操作时,其他请求需要等待锁释放。
  3. 递归处理:每次从队列中取出一个数据进行写入,写入完成后检查队列是否还有数据,如果有则继续写入,直到队列为空。

核心代码实现

const fs = require('fs');
const path = require('path');
const util = require('util');

// 异步写入文件的函数
const writeFileAsync = util.promisify(fs.writeFile);

// 待写入的文件路径
const filePath = path.join(__dirname, 'output.txt');

// 数据队列
const writeQueue = [];
// 锁变量
let isWriting = false;

// 添加数据到队列并触发写入
function enqueueWrite(data) {
    writeQueue.push(data);
    if (!isWriting) {
        processQueue();
    }
}

async function processQueue() {
    isWriting = true;
    while (writeQueue.length > 0) {
        const data = writeQueue.shift();
        try {
            await writeFileAsync(filePath, data + '\n', { flag: 'a' });
            console.log('Data written successfully:', data);
        } catch (err) {
            console.error('Error writing data:', err);
        }
    }
    isWriting = false;
}

// 示例使用
enqueueWrite('First line');
enqueueWrite('Second line');
enqueueWrite('Third line');

上述代码实现了以下功能:

  1. enqueueWrite 函数将数据添加到队列,并在队列首次有数据且当前没有写入操作时,触发队列处理。
  2. processQueue 函数负责从队列中取出数据并异步写入文件,每次写入完成后检查队列是否还有数据,继续处理直到队列为空。
  3. 使用 util.promisifyfs.writeFile 转换为Promise形式,便于使用 await 实现异步操作的顺序执行。