如何让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();
关键修改点
- 改造
Getir()为Promise风格:确保只有在文件成功写入后才resolve,让后续操作能等待它完成。 - 修正异步方法调用:用
promisify将fs的异步API转为Promise,配合async/await简化异步流程,避免回调嵌套。 - 调整执行顺序逻辑:
Mysystem()中直接用await依次调用两个函数,逻辑更清晰,避免错误的then调用方式。 - 增加异常捕获:统一处理可能出现的文件操作、HTTP请求错误。
内容的提问来源于stack exchange,提问作者CilginSinek
相关产品推荐
相关产品推荐

