其他分享
首页 > 其他分享> > 分析promise面试题

分析promise面试题

作者:互联网

Promise面试题地址: https://mp.weixin.qq.com/s/SIeDvm8nYDPK5XWzRj7LCg

Promises/A+规范: https://promisesaplus.com/

Promise的一个实现: https://github.com/taylorhakes/promise-polyfill.git

名词解释

第一题

Promise.resolve(1)
  .then((res) => {
    console.log(res)
    return 2
  })
  .catch((err) => {
    return 3
  })
  .then((res) => {
    console.log(res)
  })
1 2

首先, Promise.resolve原理如下:

Promise.resolve = function (value) {
    if (value && typeof value === 'object' && value.constructor === Promise) {
        return value
    }
    return new Promise((resolve) => { resolve(value) })
}

因为传入的value是1, 所以题目可以转化为:

new Promise((resolve) => { resolve(1) })
    .then((res) => {
        console.log(res)
        return 2
    })
    .catch((err) => {
        return 3
    })
    .then((res) => {
        console.log(res)
    })

同时, catch原理如下:

Promise.prototype.catch = function (onReject) {
    return this.then(null, onReject)
}

所以题目可以继续转化为:

new Promise((resolve) => { resolve(1) })
    .then((res) => {
        console.log(res)
        return 2
    })
    .then(null, (err) => {
        return 3
    })
    .then((res) => {
        console.log(res)
    })

从中可以看出, 一共有四个Promise:

从上面分析可知: 程序最终会打印 1 和 2

第二题

const promise = new Promise((resolve, reject) => {
    console.log(1)
    resolve()
    console.log(2)
})
promise.then(() => {
    console.log(3)
})
console.log(4)
1 2 4 3

首先, promise初始化时会传入一个函数x, 如下所示:

(resolve, reject) => {
    console.log(1)
    resolve()
    console.log(2)
}

x函数会被执行一次, 但resolve函数涉及Promise的状态转变, 而Promise自身是一个微任务, 所以resolve的执行被放到微任务队列里面, 等目前执行栈为空再清空微任务队列, 所以会首先打印 1 和 2, 此时Promise的状态还是pending, then函数的onFulfilled会存进第一个Promise的回调函数队列中, 然后打印 4, 此时执行栈空了, 开始清空微任务队列, Promise的状态从pending转为fulfilled, 同时清空自身回调函数队列, 最后打印 3

第三题

const promise1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success')
  }, 1000)
})
const promise2 = promise1.then(() => {
  throw new Error('error!!!')
})

console.log('promise1', promise1)
console.log('promise2', promise2)

setTimeout(() => {
  console.log('promise1', promise1)
  console.log('promise2', promise2)
}, 2000)

首先, promise1初始化时传入了一个函数x, 如下所示:

(resolve, reject) => {
    setTimeout(() => {
        resolve('success')
    }, 1000)
}

x函数会被执行一次, 因为setTimeout是一个宏任务, 所以会存在宏任务队列里

然后, promise2需要等待promise1的状态转变, 因此onFulfilled函数存进promise1的回调函数队列中, 此时打印promise1 和 promise2会显示Promise的pending状态

程序继续执行, 打印语句也会存进宏任务队列里, 因为延时是2000, 大于1000, 所以会在第一个setTimeout函数后面执行, 打印 promise1 的fulfilled状态和promise2 的reject状态; 如果延时是500, 则会提前执行, 还是会打印promise1 和 promise2会显示Promise的pending状态

按照我的理解, promise2中抛出的异常会被捕获到, 因此不会打印警告, 实际情况如下:

img.png

标签:分析,面试题,resolve,console,log,res,value,Promise,promise
来源: https://www.cnblogs.com/silbernitrat07/p/16644751.html