由於nodejs的異步特性,我們經常使用callback函數,但是如果在callback裏面又要callback的話,會發現多層嵌套結構非常糟糕,所以被稱爲callback Hell(“回調地獄“),採用Promise來解決這個問題。
const fs = require("fs"); const path = require("path"); const util = require("util"); //例子:判斷目標文件是否是文件夾,如果是則判斷列出目錄內的.txt文佳的大小。 //01-原始寫法,可以看到嵌套非常多層 function withOutPromise() { let target = "./abc"; fs.stat(target, (err, stats) => { if (err) { throw err } if (stats.isDirectory()) { fs.readdir(target, (err, files) => { files.forEach(f => { //console.log(f); if (path.extname(f) === '.txt') { fs.stat(path.join(target, f), (err, stats) => { console.log(f + "大小是 (字節): " + stats.size); }) } }) }) } }) }; //withOutPromise(); //a1.txt大小是 (字節): 23 // a2.txt大小是 (字節): 6 //02-使用Promise對含有回調方法的對象進行包裝 let promise=new Promise((resolve,reject)=>{ fs.readFile('./abc/a1.txt',(err,data)=>{ //resolve()方法當異步操作成功時調用 //reject()方法當異步操作失敗是調用; if (err){ reject(err); }else{ resolve(data); } }) }); //Promise調用可以A 直接調用(不推薦), B、await調用(推薦) //A promise的直接調用 //直接使用promise問題是還是需要使用回調,不建議使用。 promise.then((data)=>{ console.log("promise調用成功了!"+data) }) .catch((err)=>{ console.error("promise出異常了:"+err) }); //B 使用await語法調用 ;可以直接得到data,await需要使用async的函數。 async function withPromise() { try { let data = await promise; console.log(data.toString()); } catch (e) { console.log(e) } } //withPromise(); //03 使用until.promisify() 改寫 上面的 01-原始寫法 async function withPromiseUtil() { try { let target = "./abc"; let pstat = util.promisify(fs.stat);//包裝fs.stat let stats = await pstat(target); if (stats.isDirectory()) { let preaddir = util.promisify(fs.readdir); let files = await preaddir(path.join(target)) //console.log(files) for (let f of files) { if (path.extname(f) === '.txt') { let stat = await pstat(path.join(target, f)); console.log(f + "大小是 (字節): " + stat.size); } } } } catch (e) { console.log(e); } } withPromiseUtil(); //a1.txt大小是 (字節): 23 // a2.txt大小是 (字節): 6