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

如何让Node.js函数顺序执行?解决NewHtml.txt不存在错误

异步执行顺序错误导致文件未找到问题解决

我需要实现「创建txt文件 → 读取文件内容 → 删除文件」的流程,编写了两个函数:

  • Getir():负责创建NewHtml.txt文件
  • DegistirDuzenle():负责读取该文件并执行后续删除等操作

但现在第二个函数会先执行,报错:Error: ENOENT: no such file or directory, open './NewHtml.txt'

原代码如下:

function Getir() {
    var options =
    {
        host: 'example',
        port: 443,
        path: '/myUrl'
    };

    get(options, function (http_res) {
        var data = "";


        http_res.on("data", function (chunk) {

            data += chunk;
        });

        
        http_res.on("end", function () {
            
            writeFile('NewHtml.txt', `${data}`, 'utf8', (err) => {
                if (err) console.log(err);
            });
        });
    });
}


function DegistirDuzenle() {
    if (existsSync("./DatabaseHtml.txt")) {

        var DataBaseHtml = readFileSync("./DatabaseHtml.txt", 'utf-8', (err) => { if (err) console.log(err) });
        var MyHtml = readFileSync("./NewHtml.txt", 'utf-8', (err) => {if (err) console.log(err) });

        if (MyHtml == DataBaseHtml) {
            unlink("./NewHtml.txt", (err)=>{ if(err) console.log(err)});
            console.log("değişiklik yapılmadı");
        } else {
            //notification

            console.log("değişiklik yapıldı");

            //Change
            unlink('./DatabaseHtml.txt', (err) => { if(err) console.log(err); });
            writeFile('./DatabaseHtml.txt', `${MyHtml}`, 'utf-8', (err) => { if(err) console.log(err); });
            unlink('./NewHtml.txt', (err) => { if(err) console.log(err); });
        }

    }
    else {
        writeFile('DatabaseHtml.txt', `NewDataBaseHtml`, 'utf8', (err) => {
            if (err) console.log(err);
        });
    }
}

async function Mysystem() {
    let mypromis = new Promise((resolve, reject)=>{
        resolve(Getir());
    });
    await mypromis.then(DegistirDuzenle());
}
Mysystem();

问题原因

核心是异步操作未正确等待:

  • Getir()内部的HTTP请求和writeFile都是异步操作,但函数本身没有返回Promise,导致创建的mypromis会立刻resolve,DegistirDuzenle()提前执行,此时NewHtml.txt还未生成。
  • mypromis.then(DegistirDuzenle())直接调用了函数,而非传入函数引用,导致处理函数会被立即执行。

解决方案

修改后的完整代码

const { get } = require('https');
const { writeFile, readFileSync, existsSync, unlink } = require('fs');
const { promisify } = require('util');

// 将fs异步方法转为Promise风格
const writeFileAsync = promisify(writeFile);
const unlinkAsync = promisify(unlink);

function Getir() {
    return new Promise((resolve, reject) => {
        const options = {
            host: 'example',
            port: 443,
            path: '/myUrl'
        };

        get(options, (http_res) => {
            let data = "";

            http_res.on("data", (chunk) => {
                data += chunk;
            });

            http_res.on("end", async () => {
                try {
                    await writeFileAsync('NewHtml.txt', data, 'utf8');
                    resolve(); // 文件写入完成后再resolve
                } catch (err) {
                    console.log(err);
                    reject(err);
                }
            });

            http_res.on("error", reject);
        }).on('error', reject);
    });
}


async function DegistirDuzenle() {
    if (existsSync("./DatabaseHtml.txt")) {
        try {
            const DataBaseHtml = readFileSync("./DatabaseHtml.txt", 'utf-8');
            const MyHtml = readFileSync("./NewHtml.txt", 'utf-8');

            if (MyHtml === DataBaseHtml) {
                await unlinkAsync("./NewHtml.txt");
                console.log("değişiklik yapılmadı");
            } else {
                console.log("değişiklik yapıldı");

                // 按顺序执行异步操作,避免竞态问题
                await unlinkAsync('./DatabaseHtml.txt');
                await writeFileAsync('./DatabaseHtml.txt', MyHtml, 'utf-8');
                await unlinkAsync('./NewHtml.txt');
            }
        } catch (err) {
            console.log(err);
        }
    } else {
        try {
            await writeFileAsync('DatabaseHtml.txt', 'NewDataBaseHtml', 'utf8');
        } catch (err) {
            console.log(err);
        }
    }
}

async function Mysystem() {
    await Getir(); // 等待文件创建完成
    await DegistirDuzenle(); // 再执行读取删除逻辑
}

Mysystem();

关键修改点

  1. 改造Getir()为Promise风格:确保只有在文件成功写入后才resolve,让后续操作能等待它完成。
  2. 修正异步方法调用:用promisify将fs的异步API转为Promise,配合async/await简化异步流程,避免回调嵌套。
  3. 调整执行顺序逻辑:Mysystem()中直接用await依次调用两个函数,逻辑更清晰,避免错误的then调用方式。
  4. 增加异常捕获:统一处理可能出现的文件操作、HTTP请求错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:10:13