由于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