Nodejs进阶系列- 08 使用 Promise/await/async解决 callback hell

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

发布了40 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/LUCKWXF/article/details/104222643
今日推荐