通俗方法串联理解js中常用的callback,promise以及async await

假设有一堆人要去上厕所,然而厕所只能同时容纳固定的人数。这时候有个管理员坐在厕所门口,由他来决定一个人可不可以进入厕所,如果不可以则返回err,如果可以则返回data,这是callback function,以读取文件为例,“不可以”按照规矩要优先抛出,就像是管理员告诉你“里面满了”比“可以进去”要优先一样。

const fs = require('fs');

fs.readFile('./test.js', 'utf-8', (err, data) => {
    if(err){
        console.log("Err: ");
        console.log(err);
    }else{
        console.log("Data: ");
        console.log(data)
    }
})

假设有人非常困惑自己应该进哪边的厕所,那么这个时候,我们定下一个规矩,即“这个世界上只存在男人和女人”,这就是promise,其英文直译为“保证”,保证什么呢?保证你一定是男人,或者是女人。也就是说,虽然管理员现在不知道你现在是男人还是女人,但你终究必然是男人或者女人。正因为如此,我们把这个不知道是男人还是女人的人交给管理员让他决定可不可以进厕所这件事。
promise对象就是这个人目前的代称,这个对象有三种状态,即pending,fulfilled和rejected,对应着“悬而未决”,“已经解决”和“已经拒绝”。这个对象里面有一个函数,这个函数接收两个参数即(resolve, reject)对应着我们所说的决定是男是女这件事,这两个参数也是两个函数,分别用来决定,如果是男人怎么办和如果是女人怎么办这两件事。
拿到promise对象之后,用.then来写,对于.then后出来的东西,依然是前面的resolve和reject这两个函数,这两个函数既是输入又是输出,我们要处理的data都是在这两个函数里面处理的。promise对象.then之后依然是promise对象。

const fs = require('fs');

function readFile(filename, encoding) {
    const fn = (resolve, reject) => {
        fs.readFile(filename, encoding, (err, data) => {
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        });
    };
    return new Promise(fn);
}


readFile('./test.js', 'utf-8')
    .then(
        (data) => {
        console.log("data: ")
        console.error(data);
    },
        (err) => {
            console.log("err: ")
            console.log(err);
        }
        )

最后,async await关键字本质上是一种语法糖,它的存在,单纯只是将promise进行一种改写,使得代码可读性更高。
async关键字保证函数返回的是一个promise对象,而所有返回的data都被包在这个promise对象的resolve函数里面,只要通过await关键字就可以拿到这些data。上面的promise对象被改写成一行代码能够解决,注意,这里我要求了fs模块返回promises对象给我,而不是像之前一样用callback的形式。

const fs = require('fs').promises

async function readFile(url, encoding) {
    return await fs.readFile(url, encoding);
}

readFile('./test.js', 'utf-8')
    .then(
        data => {
            console.log(data);
        },
        err => {
            console.log(err);
        }
    )
    

进一步用try, catch, finally和IIFE来改写。本质上,try,catch,finally都是then的变体,then返回的是resolve和reject两个callback函数,而try相当于返回resolve和null,catch相当于返回null和reject,finally则无论返回resolve还是reject都不做处理,相当于返回resolve/reject,这样写的好处就是省了在then里面一般需要写两个函数.then(f,f)的语法(虽然then也可以只写resolve),说白了就是省事。

const fs = require('fs').promises;

(async function () {
    try {
        const data = await fs.readFile('./test.js', 'utf-8');
        console.log(`Data: ${data}`);
    }
    catch(err){
        console.error(err);
    }
    finally{
        console.log('-----------');
    }
})();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值