为什么Node.js的fs.readFile回调输出晚于后续同步console.log语句?
问题解答
执行顺序异常的原因
Node.js 采用单线程事件循环的运行架构,你调用的 fs.readFile 属于异步非阻塞I/O接口:调用该方法后,Node 会将文件读取任务交给底层 libuv 线程池处理,主线程不会等待 I/O 操作完成,会直接继续执行后续的同步代码 console.log('hello shawn!')。等文件读取完成后,对应的回调函数才会被推入任务队列,等待主线程空闲时执行,因此会出现回调内的输出晚于后续同步代码的情况。
优先读取文件再执行后续逻辑的实现方案
方案1:使用同步读取API
直接调用 fs.readFileSync 同步阻塞方法,主线程会等待文件读取完成后再往下执行后续代码:
const fs = require('fs'); try { // 同步读取会阻塞主线程,直到读取完成/报错 const data = fs.readFileSync('./assets/test1.txt'); console.log(data.toString()); } catch (err) { console.log(err); } // 读取完成后才会执行这行 console.log('hello shawn!');
方案2:将后续逻辑移入异步回调
把要在文件读取完成后执行的代码,全部放到 fs.readFile 的回调函数内部,保证执行顺序:
const fs = require('fs'); fs.readFile('./assets/test1.txt', (err, data) => { if(err){ console.log(err) } console.log(data.toString()) // 后续逻辑全部放在回调内执行 console.log('hello shawn!') })
方案3:使用Promise + async/await写法(推荐)
用Node.js官方提供的 promise 版fs API,结合async/await语法,既保留非阻塞特性,又能保证执行顺序,代码可读性更高:
const fs = require('fs').promises; // 封装异步执行函数 async function execTask() { try { const data = await fs.readFile('./assets/test1.txt'); console.log(data.toString()); // 读取完成后执行后续逻辑 console.log('hello shawn!'); } catch (err) { console.log(err); } } execTask();
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

