有趣且重要的JS知识合集(5)JS事件循环机制和Promise

具体详解事件处理当中的宏观任务,微观任务,很多博客都在讲,我这里就不细说了,我只是通俗写一下我的理解:

1、宏观微观任务:

我们浏览器用得多的宏观任务是setTimeout、setInternal,微观任务是promise.then,一般也都是这三种任务混合触发,然后让你写出触发顺序,总结一下就是,有同步代码就执行同步代码(new Promise 也属于同步代码,promise.then才属于微观),没同步代码,就执行异步,有微观就执行微观,有多少执行多少,执行完以后,就执行宏观中的一个(注意是一个),然后再次开启下次循环。这还蛮好理解的, 同步>异步微观>异步宏观

2、Promise

Promise是我们用的最多的微观任务,axios依赖的就是这promise,先说下promise一共三状态,两回调,具体概念很多博客有介绍,我这就不写了,关键点是:

2.1、我们知道可以在new Promise里面通过写入reject() 来进入.then方法的第二回调(即失败回调)或者进入catch(有catch的话),那如何在promise.then()里面,主动触发失败方法呢?

new Promise((resolve, reject) => {
    resolve('参数')
}).then(成功回调0, 失败回调0).then(成功回调1, 失败回调1).catch()

我们想要在成功回调0里,进到第二步的失败回调1,做法就是在成功回调0里, 写入 throw new Error(异常类型有六种我记着是,这里我举一个例子为 Error 类型),如果下一个.then有失败回调(我这个例子就有),就会被失败回调所捕捉,切记,一旦被捕捉,就不会再被catch所捕捉(意思就是只会被捕捉一次)

举个栗子:

new Promise((resolve, reject) => {
    resolve('参数')
})
.then((e)=>{throw new Error('123')}, ()=>{})
.then(()=>{}, (e)=>{console.log(e.message, '异常1')})
.catch(e=>{console.log(e.message, '异常2')})

//打印 
// 123 异常1

这里科普一个小知识点, throw抛出错误, 在捕捉错误时,回调参数 e 有两属性值: message 和 name,throw new name(message), 这里就写的很清楚了,但是这name只有固定那几种了

2.2、无论是.catch还是.then后面,只要还有这种链式方法,就是一直运行下去

就算你已经运行到.catch了,如果你.catch 后面还有 .then,那么会继续运行下去,并且会以 成功状态继续运行

举个栗子:

new Promise((resolve, reject) => {
    resolve('参数')
})
.then((e)=>{throw new Error('123')}, ()=>{})
.then(()=>{}, (e)=>{console.log(e.message, '异常1')})
.catch(e=>{console.log(e.message, '异常2')})
.then(e => console.log(e, '成功1'))


//打印 
// 123 异常1
// undefined '成功1'

那这是为啥呢,你也可以这么理解,这种操作叫作 复式,意思即.then(), .catch() 都是返回 Pormise对象,只有后面还有链式调用,会一直这种运行下去,那我们知道,为什么失败调用运行后,就直接进到.then的成功回调呢, 其实这涉及到Promise.then()的返回值情况了,要想具体了解的,可以看下mdn上对Promise这部分的详解,我这里还是说下我的理解,promise.then()返回我们分为四种(我自己理解为4种,这针对我更好理解,官方分的更细,为6种),就是在 .then()里到底返不返回,返回啥?

2.2.1、return 值

new Promise((resolve, reject) => {
    resolve()
})
.then(() => '成功参数').then(e => e)

像这种,就是我们用的最多的一种,下一个.then的参数e就是上一个.then的 return 出来的值

2.2.2、不做操作

new Promise((resolve, reject) => {
    resolve()
})
.then(() => {console.log('我就是想打印一下')})
.then(e => {console.log(e)})

// 打印
// 我就是想打印一下
// undefined

有些时候,你就是想玩玩,不想将数据传递下去,面试题很多是这样,那么你这个时候输出e,就会是undefined,那是为啥呢,因为下一个.then都是接收上一个return出来的值,要是上一个不return的话,那参数就是undefined

2.2.3、主动抛错误

这个我们上面2.1详细讲了

2.2.4、返回值为promise

这个咋理解呢,其实也蛮好理解,我们不是在.then里面return 一个值吗,把这个值,改成一个promise,就可以呢,那你就会想,返回promise和返回值 有啥区别呢?其实吧,从结果来讲,是没区别的,因为在下一个.then的参数,用的也是你上一个.then最终的结果

举个栗子:

Promise.resolve("成功参数0")
  .then(e => {
    return new Promise(function(resolve, reject) {
      setTimeout(function() {
        e += '宏观'
        resolve(e);
      }, 100);
    });
  })
 .then(e => {
    console.log(e)
 })

// 打印
// Promise {<pending>}
// 成功参数0宏观

看,第一个.then()返回值是promise,然后promise里面居然有个宏观任务,那是不是看到上面第一点讲的宏观微观任务啦,先执行微观,在执行宏观,我相信大多数人和我第一次想的一样,那肯定先执行第二个.then,在执行setTimeout呢,其实这里不是,有return的地方,就要先执行return,所以我们就执行了 第一个.then的resolve,然后再执行第二个.then,切记,有return地方,都会一定执行return,不管你return 返回的是宏观还是微观任务

大家也可以根据这个例子,向外面发散,多写些console.log这种同步,或者自己加些异步代码,也可以直接参考mdn上 promise.then的示例代码,链接如下

promise.then()

2.3、promise常用方法

promise我们其实用的最多的,除了.then,.catch,.finally这种原型方法,还有以下静态方法

Promise.all() 
// 用的最多,用于执行很多异常代码,
// 然后按顺序返回这些异步的结果,但当
// 出现一个失败,就会直接返回失败的那
// 个异步结果,这很像Array的方法 every, 
// 全部成功才是成功,有一个失败即失败

Promise.race() 
// 返回执行最快的异步结果,无论是成功
// 结果还是失败结果

Promise.any() 
// 返回一个成功的异步结果,注意是成功结果,
// 这很像Array的方法 some, 有一个成功即为成功

Promise.resolve() 
// 直接进入成功回调

Promise.reject() 
// 直接进入失败回调

Promise.allSettled() 
// 无论成功
// 结果还是失败结果,都要全部运行完,这个
// 就和.all有差异,全成功的话,这俩方法一样,
// 有失败的话,.all立即终止并返回失败的那个
// 结果,.allSettled是有失败,接着运行,直
// 到全部都运行完,注意:不会被catch或者.then
// 第二回调捕捉

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值