You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fs.readFile回调转文件为base64时出现无限循环问题

为什么使用fs.readFile的Promise封装会导致无限循环?

问题核心

你的代码里的致命问题是Promise从未被正确决议(resolve)。在fs.readFile的回调函数中,你最后只是返回了拼接好的base64字符串,但完全没调用resolve()把结果传递给Promise的调用者。这会导致你创建的Promise一直处于pending(挂起)状态,永远不会完成。

如果你的调用方(比如业务逻辑或框架代码)存在等待Promise完成的重试机制(比如循环检测Promise状态),就会触发无限循环——因为Promise永远不会被标记为完成,调用方会一直重试下去。

错误代码的关键问题点

看这段核心代码的问题:

return new Promise((resolve, reject) => {
    const filePath = "some/path";

    fs.readFile(filePath, {encoding: "base64"}, (err, data) => {
        if (err) {
            reject(err);
            return;
        }
        // 这里的返回值对Promise毫无意义,必须调用resolve传递结果
        return `data:${file.getMimeType()};base64,${data}`;
    });
});

回调函数的返回值不会被Promise捕获,只有调用resolve()才能把结果传递出去,让Promise进入fulfilled(完成)状态。

正确的Promise封装写法

把回调里的返回操作改成调用resolve:

import fs from 'fs';

@Service()
export class FileHandler {
    public async toBase64(file: MediaFile): Promise<string> {
        return new Promise((resolve, reject) => {
            const filePath = "some/path";

            fs.readFile(filePath, {encoding: "base64"}, (err, data) => {
                if (err) {
                    reject(err);
                    return;
                }
                // 调用resolve传递最终结果
                resolve(`data:${file.getMimeType()};base64,${data}`);
            });
        });
    }
}

另外,Node.js的fs模块已经提供了Promise化的API,完全不用手动封装,代码会更简洁:

import fs from 'fs/promises'; // 导入Promise版本的fs模块

@Service()
export class FileHandler {
    public async toBase64(file: MediaFile): Promise<string> {
        const filePath = "some/path";
        const data = await fs.readFile(filePath, {encoding: "base64"});
        return `data:${file.getMimeType()};base64,${data}`;
    }
}

补充说明

你用readFileSync解决问题是因为同步方法会直接阻塞并返回结果,不会产生挂起的Promise,自然不会触发调用方的重试逻辑。但同步方法会阻塞Node.js的事件循环,在高并发场景下不推荐使用,优先选择Promise化的异步API更合理。

内容的提问来源于stack exchange,提问作者bkrnetic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 13:37:38