javascript - Node.js中輸出順序為什么和預(yù)期的不一樣呢?
問題描述
考察下面的代碼,它用于用于輸出指定目錄下的文件
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); //否則遞歸調(diào)用 }}file(0);//開始執(zhí)行 }});
上述代碼輸出的結(jié)果我不能理解,按照這個程序設(shè)計的邏輯,應(yīng)該先是把目錄下所有文件都列出來,然后計數(shù)器i==files.length后才輸出“輸出完畢”這個終結(jié)語。
如上圖所示,不但“輸出完畢”這個終結(jié)語最先輸出,而且打印順序完全是錯亂的,多次運行的打印順序也不穩(wěn)定。
我在想是不是異步調(diào)用有時間差,所以將上述代碼sleep(1000)注釋部分去掉,但是結(jié)果依然與我所預(yù)期不一致:“文件如下”提示語先輸出,此后停止1s后,后續(xù)語句幾乎同時出,沒有停頓,并且“輸出完畢”這個終結(jié)語依然第一個被打印。
綜上所述,我想知道的是
為什么打印結(jié)果不穩(wěn)定,為什么“輸出完畢”這個提示語首先被輸出?
為什么加上sleep(1000)這個暫停語句后,只有一開始停了1s,后面不再暫停而是同時輸出?
如何解決這個問題,即如何在修改盡可能少的情況下讓“輸出完畢”這個提示語最后輸出?
謝謝各位大佬賜教!
問題解答
回答1:fs.stat是異步操作,所以你的輸出文件信息都是異步執(zhí)行的,“輸出完畢”肯定先打印的。想同步可以用這個https://nodejs.org/docs/lates...
在sleep里加個console.log(’sleep’)看是不是 只輸出一次?
如果你想保證輸出文件信息之后才輸出“輸出完畢”,第一點里我提到的用fs.statSync估計修改比較少吧
回答2:根據(jù)@Dont的回答,確實是異步方法調(diào)用的原因,因為fs.stat的回調(diào)函數(shù)是在事件輪詢中被調(diào)用,它一般在主程序運行間隙時候被調(diào)用,被調(diào)用時間和順序不定。使用statSync方法可以實現(xiàn)同步:
(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++; ................
相關(guān)文章:
1. docker鏡像push報錯2. angular.js - angular內(nèi)容過長展開收起效果3. Docker for Mac 創(chuàng)建的dnsmasq容器連不上/不工作的問題4. javascript - URL中有#號如何來獲取參數(shù)啊? nodejs5. docker容器呢SSH為什么連不通呢?6. docker不顯示端口映射呢?7. 關(guān)于docker下的nginx壓力測試8. 新手求教python3如何把dict循環(huán)寫入csv文件(在進行爬蟲時遇到的問題)?9. python - 想要看Exception實現(xiàn)的源碼在什么位置?10. python - Django表單Form.save()問題
