promise面试题--从源码说

前面几篇文章已经大致理清楚了promise的语法、promise的使用以及手写了一个promise。今天就基于此,做一些promise常见的面试题,以巩固自己的知识
为什么promise resolve了一个value, 最后输出的value值却是undefined
promise面试题--从源码说
文章图片
promise面试题--从源码说
文章图片
解析:
new Promise中回调函数的代码是同步任务会被立即执行,遇到setTimeout是异步任务。在通过.then回调时由于上一个的状态为pending,故会存储到队列中并监听status改变,30秒后由pending到fulfilled执行then回调,获取到value为1
then内部也会返回一个promise,并且会对返回值进行解析,对于非promise、对象、函数类型的返回值会直接resolve,这里回调内未显示的返回故取默认的undefined,故.then的resolve设置的value为undefined
为什么我在catch的回调里, 打印promise, 显示状态是pending
promise面试题--从源码说
文章图片
promise面试题--从源码说
文章图片
解析:
根据上一题分析我们知道, 如果是通过.then获取值的话,那么一秒之后将会执行。经过手写promise章节我们知道了.catch内部仍然是走的.then方法,故1秒之后将会执行.catch。当.catch执行完毕后将调用resolve或reject修改状态。而console.log(questionTwo)是执行中,故此时状态还未改变仍为pending
请输入以下代码的打印结果并解释说明.catch
promise面试题--从源码说
文章图片
promise面试题--从源码说
文章图片
解析:
由于是同步代码,故1被打印
执行resolve,将status修改为fulfilled
由于回调尚未执行完毕,则继续向下,打印2
执行reject,由于此时状态已经被修改了,故这一句代码实际并未执行,故.catch不会被触发
调用实例的then去获取上一个promise的结果,由于我们在代码中使用了queueMicrotast将onFulfill和onReject包裹成了微任务,故此时不会执行
打印4,此时主线程结束,浏览器访问任务队列,此时才调用onFulfilled打印3
请使用一种方式取消promise
【promise面试题--从源码说】实现一
我们知道,一个promise的状态只允许被改变一次,就像上一题一样,resolve和reject谁先调用则以谁为准。那么我们只需要将reject向外抛出并在适当的时机调用即可
promise面试题--从源码说
文章图片
(rejectFunc时状态被修改为rejected,监听到status改变执行 REJECTED_CBS 打印absort) 实现二
由于race会选择速度最快的那一个promise作为最终的返回值,并且我们知道race内部求值是去按照数组的次序依次进行的,故我们只需要定义一个同步的promise并放在数组的第一位即可
promise面试题--从源码说
文章图片
解释下为什么输出的不是3
promise面试题--从源码说
文章图片
解析:
静态的resolve会将1包裹成promise且同步修改其status为fulfilled并返回
.then如果传入的不是一个函数,我们在代码中将其默认成了(value)=>value,则第二和第三处都是
当跑完三个.then后没有更多任务时,浏览器调用微任务队列进行执行,第二处的.then对应的回调被执行,返回上一个promise的值,即1
promise面试题--从源码说
文章图片
第二个.then同理,返回1
故最终输出1
在不使用async/await的情况下,顺序执行一组异步代码函数,并输出最后的结果
利用reduce每次对前一个promise进行求值并将当前的promise替换为下一次的待求值。我们知道.then中如果返回了promise,则会调用parsePromise进行解析并求值。即第一次对success3求值,第二次success5,第三次success0。同时,是异步的,故会等待,并监听status改变,即questionSix_1在3秒后改变其状态,向questionSix_2传递值。questionSix_2在2秒后改状态并向下传递,最后是questionSix_3
promise面试题--从源码说
文章图片
promise面试题--从源码说
文章图片

    推荐阅读