• Promise 中为什么要引入微任务?
  • Promise 中是如何实现回调函数的返回值穿透的?
  • Promise 出错后,是怎么通过“冒泡”传递给最后那个捕获异常的函数?

为什么要引入微任务?

  1. function PromiseB(executor) {
  2. var onResolve_ = null
  3. var onReject_ = null
  4. this.then = (onResolve, onReject) => {
  5. onResolve_ = onResolve
  6. }
  7. function resolve(value) {
  8. // setTimeout(() => {
  9. onResolve_(value)
  10. // },0)
  11. }
  12. executor(resolve, null)
  13. }
  14. /**
  15. * 如果不用微任务,resolve 内部调用 onResolve_ 时,then 没执行,onResolve_ 为 null,报错。
  16. * 所以要用微任务实现回调函数的延时绑定
  17. */
  18. let test = new PromiseB((resolve) => {
  19. resolve(100)
  20. })
  21. test.then((val) => {
  22. console.log(val)
  23. })

问答

  • Ajax 是宏任务,Promise 是微任务,在 Promise 中调用 Ajax,是宏任务还是微任务?
    在 Promise 的 executor 中调用 XMLHttpRequest 会触发宏任务,如果请求成功了,通过 resolve 触发微任务。如果请求失败了,通过 reject 触发微任务。
  • 1、Promise 中为什么要引入微任务?
    由于promise采用.then延时绑定回调机制,而new Promise时又需要直接执行promise中的方法,即发生了先执行方法后添加回调的过程,此时需等待then方法绑定两个回调后才能继续执行方法回调,便可将回调添加到当前js调用栈中执行结束后的任务队列中,由于宏任务较多容易堵塞,则采用了微任务
  • 2、Promise 中是如何实现回调函数返回值穿透的?
    首先Promise的执行结果保存在promise的data变量中,然后是.then方法返回值为使用resolved或rejected回调方法新建的一个promise对象,即例如成功则返回new Promise(resolved),将前一个promise的data值赋给新建的promise
  • 3、Promise 出错后,是怎么通过“冒泡”传递给最后那个捕获?
    promise内部有resolved和rejected变量保存成功和失败的回调,进入.then(resolved,rejected)时会判断rejected参数是否为函数,若是函数,错误时使用rejected处理错误;若不是,则错误时直接throw错误,一直传递到最后的捕获,若最后没有被捕获,则会报错。可通过监听unhandledrejection事件捕获未处理的promise错误

参考资料

手写一个 Promise