分析promise面试题
作者:互联网
Promise面试题地址: https://mp.weixin.qq.com/s/SIeDvm8nYDPK5XWzRj7LCg
Promises/A+规范: https://promisesaplus.com/
Promise的一个实现: https://github.com/taylorhakes/promise-polyfill.git
名词解释
- onFulfilled: then的第一个参数, 默认提供函数
- onRejected: then的第二个参数, 默认提供函数
第一题
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:
- 第一个Promise: 从resolve(1)可以看出, 自身Promise状态从pending转化为fulfilled, value = 1
- 第二个Promise: 因为第一个Promise的状态是fulfilled, 所以它的value是onFulfilled函数的第一个参数, 即 res = 1; 因为onFulfilled函数返回一个x, 且x既不是函数也不是对象, 所以自身Promise状态从pending转化为fulfilled, value = 2
- 第三个Promise: 因为onFulfilled不是一个函数, 所以自身状态从pending转换为fulfilled, value是第二个Promise的value, 即 value = 2
- 第四个Promise: 因为第三个Promise的状态是fulfilled, 所以它的value是onFulfilled函数的第一个参数, 即 res = 2;
从上面分析可知: 程序最终会打印 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中抛出的异常会被捕获到, 因此不会打印警告, 实际情况如下:
- 谷歌浏览器 version: 104.0.5112.101
标签:分析,面试题,resolve,console,log,res,value,Promise,promise 来源: https://www.cnblogs.com/silbernitrat07/p/16644751.html