javascript - Node.js中输出顺序为什么和预期的不一样呢?
问题描述
考察下面的代码,它用于用于输出指定目录下的文件
var fs=require(’fs’);function sleep(numberMillis) { //sleep方法,暂停numberMillis毫秒 var now = new Date(); var exitTime = now.getTime() + numberMillis; while (true) { now = new Date(); if (now.getTime() > exitTime) return; } }fs.readdir(__dirname,function(err,files){ //文件读取方法 console.log(’’); if(!files.length){console.log(’找不到文件 n’); }else{console.log(’文件如下:’);function file(i){ var filename=files[i]; fs.stat(__dirname+’/’+filename,function(err,stat){if(stat.isDirectory()){ console.log(’ ’+i+’文件夹:’+filename+’/...’);}else{ console.log(’ ’+i+’文件:’+filename+’’);} }); i++; //sleep(1000); //。。。。。。。。######暂停1sif(i==files.length){console.log(’输出完毕’); }else{file(i); //否则递归调用 }}file(0);//开始执行 }});
上述代码输出的结果我不能理解,按照这个程序设计的逻辑,应该先是把目录下所有文件都列出来,然后计数器i==files.length后才输出“输出完毕”这个终结语。
如上图所示,不但“输出完毕”这个终结语最先输出,而且打印顺序完全是错乱的,多次运行的打印顺序也不稳定。
我在想是不是异步调用有时间差,所以将上述代码sleep(1000)注释部分去掉,但是结果依然与我所预期不一致:“文件如下”提示语先输出,此后停止1s后,后续语句几乎同时出,没有停顿,并且“输出完毕”这个终结语依然第一个被打印。
综上所述,我想知道的是
为什么打印结果不稳定,为什么“输出完毕”这个提示语首先被输出?
为什么加上sleep(1000)这个暂停语句后,只有一开始停了1s,后面不再暂停而是同时输出?
如何解决这个问题,即如何在修改尽可能少的情况下让“输出完毕”这个提示语最后输出?
谢谢各位大佬赐教!
问题解答
回答1:fs.stat是异步操作,所以你的输出文件信息都是异步执行的,“输出完毕”肯定先打印的。想同步可以用这个https://nodejs.org/docs/lates...
在sleep里加个console.log(’sleep’)看是不是 只输出一次?
如果你想保证输出文件信息之后才输出“输出完毕”,第一点里我提到的用fs.statSync估计修改比较少吧
回答2:根据@Dont的回答,确实是异步方法调用的原因,因为fs.stat的回调函数是在事件轮询中被调用,它一般在主程序运行间隙时候被调用,被调用时间和顺序不定。使用statSync方法可以实现同步:
(function file(i){ var filename=files[i]; function read(stat){if(stat.isDirectory()){ console.log(’ ’+i+’ 033[36m 文件夹:’+filename+’/...033[39m’);}else{ console.log(’ ’+i+’ 033[36m 文件:’+filename+’033[39m’);} }; read(fs.statSync(__dirname+’/’+filename)); i++; ................
相关文章:
1. java固定键值转换,使用枚举实现字典?2. vim - win10无法打开markdown编辑器3. mysql - 千万数据 分页,当偏移量 原来越大时,怎么优化速度4. 如何解决tp6在zend中无代码提示5. javascript - 有没有类似高铁管家的时间选择插件6. 这是什么情况???7. python - flask学习,user_syy添加报role is invalid keyword for User.8. css - BEM 中块(Block)有木有什么标准 何时决定一个部分提取为块而不是其父级的元素呢(Element)?~9. css3 - less或者scss 颜色计算的知识应该怎么学?或者在哪里学?10. javascript - 微信网页开发从菜单进入页面后,按返回键没有关闭浏览器而是刷新当前页面,求解决?
