代码实现
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
const concurrentLimit = require('async-concurrent-limit');
const writeFileAsync = promisify(fs.writeFile);
const stringArrays = [
['line1', 'line2'],
['line3', 'line4']
];
const filePaths = ['file1.txt', 'file2.txt'];
async function writeFiles() {
try {
const writeTasks = stringArrays.map((arr, index) => async () => {
const content = arr.join('\n');
await writeFileAsync(path.join(__dirname, filePaths[index]), content);
console.log(`Successfully wrote to ${filePaths[index]}`);
});
await concurrentLimit(writeTasks, writeTasks.length);
} catch (error) {
console.error('An error occurred during file write:', error);
// 这里可以添加终止所有并发操作的逻辑,例如取消未完成的任务
}
}
writeFiles();
高效写入和并发控制策略的理解
- 高效写入:
- 使用异步 I/O:在 Node.js 中,使用
fs.writeFile
的异步版本(通过 promisify
转换为 Promise 形式),这样在进行文件写入时不会阻塞主线程,允许其他代码继续执行,提高整体的效率。
- 缓冲区使用:虽然上述代码未显式设置缓冲区大小,但在底层
fs.writeFile
操作中,合理的缓冲区大小可以减少系统调用次数,提高写入效率。例如,较大的缓冲区适合连续写入大量数据,减少频繁的系统调用开销。
- 并发控制策略:
- 并发数量限制:通过
async - concurrent - limit
库(这里假设安装并引入了该库),可以控制并发操作的数量。在上述代码中,将并发数量设置为任务数组的长度,确保所有任务并发执行。但在实际应用中,如果任务较多且系统资源有限,可能需要限制并发数量为一个较小的值,避免过多的并发操作耗尽系统资源(如文件描述符等)。
- 错误处理与终止:当某个
writeFileAsync
操作抛出错误时,try - catch
块捕获错误,打印错误信息,并可以在 catch
块中添加终止其他未完成并发操作的逻辑。例如,如果使用的是 Promise.allSettled 管理并发任务,可以通过标记变量或其他方式取消未完成的任务,防止不必要的资源浪费。