00:00
哈喽,大家好,这一个小节呢,我们来看一下promise当中的关键问题。第三个。就是改变promise对象的状态与指定回调函数谁先谁后。这里的谁先谁后呢?指的是直行的谁先谁后。那么改变状态我们在前面已经介绍过了。用reject through。啊,我们这里为了就是方便去区分先后顺序,所以说我们就以resolve来为例。那么第二一个呢,就是指定回调函数。指定回调函数咱们用谁呢?我们可以用Z,用catch,在这儿呢,我们也是选一个用then。所以说这个题目它的问题可以这样子来进行一个简化,在代码层面上进行一个简化,那就是我的promise代码在运行时resolve改变状态先执行,还是Z方法这个指定回调先执行。
01:04
我呢,先写一个代码结构给大家演示一下,要不然光去想呢,可能想的。不是很全。我呢首先在这呢,写一个promise的代码结构,然后在里边,哎,我先在这儿啊,下边的话来一个p.Z。啊,这是成功的,再来一个失败的回调。好,然后呢,在里边呢,我去写resolve,改变状态。那么这个问题就是我改变状态的resolve和Z方法指定回调。这个函数他们两个,谁先谁后,就谁先执行,谁后执行。那么在这儿呢,两种情况都是有可能出现的。也就是说,你有可能呢是resolve,先改变状态再执行Z方法,也有可能是Z方法先指定回调再去。
02:02
啊,再去这个,呃,用resolve改变状态。那么这两种情况会在什么时候发生呢?啊,我们首先先来看一下第一种情况,那就是我什么时候先去执行这个resolve,改变状态后去指定回调呢?就是当这一个执行器函数当中的任务是一个同步任务,你直接去调resolve的时候,在这种情况下,那就是先改变promise队形的状态,然后再去指令回调。好了,我来输出一下。看一下这个结果,这个结果是一定能够啊正确去执行的,你可以看一下,OK,没有问题。那么还有另外一种情况,那就是我什么时候Z方法先执行,然后resolve改变状态后执行呢?就是当这一个执行器函数当中,它是一个异步任务的时候。
03:06
也就是说我改变状态呢,是需要等待一段时间。啊,需要进到这个对应的模块,通过队列去执行的时候,在这种情况下就是Z方法,它先执行改变状态呢后执行。而且这个代码也是能够正常去运行的,大家可以看一下,等一秒这个OK也会输出。所以说在这块两种情况呢,它都存在。好了,而且呢,在实际使用promise的时候,这种情况是居多的,哪种情况呢?就是它是一个异步任务的时候是居多的,你比如说咱们封装FS进行文件操作,还有呢,进行数据库操作,还有阿贾克斯操作的时候,那么这块都是一个异步的任务。好了,那么下边的话咱们切过来啊,来看一下。
04:03
如何先改变状态,再指定回调?我们刚才说了,在执行器函数当中呢,你做一个同步任务,直接去调resolve reject就可以先改状态,再去指定回调。啊,像刚才这样子同步任务。是先指定回调啊,先改变状态再指定回调的。那么还有一种情况就是我延迟更长的时间再去调用Z方法。这个是什么意思呢?你比如说我这块呢,是一秒钟。然后去执行resolve,我下边的Z方法呢,我可以加一个两秒的定时器,再去执行Z方法,那么这个时候也是它先改变状态,然后再去指定回调。好了,这是。这个情况,那对于另外一种情况,什么时候先指定回调再改变状态呢?咱们说了里边这块是一个异步任务的时候,你在异步回调当中去调resolve,调reject,那就是先指定回调后去改变状态。
05:09
好了,那么下边呢,还有一个小点,就是我什么时候才能拿到数据,其实这个什么时候才能拿到数据,指的就是我的回调函数到底什么时候执行。这个回调函数它什么时候执行,我们分开来说,如果我是先改了状态。啊,如果我是先给的状态,就里边我是立即调了resolve,那么在这种情况下,Z方法在调用的时候就会去执行回调函数来处理它成功或者失败的结果。那么如果说。我是一个什么呀,我是先指定的回调,像这种情况啊,后去改变状态,在这种情况下是我改变状态以后。再去调用成功或失败的结果。
06:05
注意,这个问题很关键,这是我们整个的封装当中非常非常重要的一个环节。在这种情况下,就是你先指定回调,再去改变状态,这种情况下回调的执行时机是在调用完,就是调用resolve以后。再去执执,再去执行这个回调函数里边代码,然后对成功或者失败的结果去做一个处理。是这样的一个情况。那么这个问题其实简单来去认,简单来去表述的话,就是我这个执行器函数当中,可以是一个同步任务,也可以是一个异步任务,两种情况promise都是支持的。当然,至于内部怎么实现,那么后期到了后边咱们会给大家讲解具体的实现原理,好了,这个问题我们就先到这儿。
我来说两句