目前我是刚转行,准备进入前端(原本专业是心理学,但心理学不好就业....),然后碰到这样这样一个Promise的面试题,觉得很有趣,特别分享一下
题目如下:
Promise.resolve().then(() => {
console.log(0); //
return Promise.resolve(4); //
}).then((res) => {
console.log(res)
})
Promise.resolve().then(() => {
console.log(1); //
}).then(() => {
console.log(2); //
}).then(() => {
console.log(3); //
}).then(() => {
console.log(5); //
}).then(() => {
console.log(6); //
})
正确的输入结果是 0 1 2 3 4 5 6 我当初的算的结果是 0 1 2 4 3 5 6
思路
- 我先说说我的思路(错误的)
- 首先执行 console.log(0)
- 然后执行return Promise.resolve(4),因为Promise.resolve(4)会发返回一个状态为‘fulfilled’的Promise对象,所以这里是return一个Promise对象,当Promise.then()return一个Promise对象时,会发起一个微任务队列,至于为什么是一个微任务队列,我手写一下Promise,来说明
可以不用看我前面手写的构造函数,直接看最下面的then函数,在我的想法里,当return一个Promise对象时,这个Promise对象会再次执行一下then方法,于是会再次发起一个微任务队列
- 所以是 0 1 2 4 3
class newPromise {
//构造方法
constructor(executor) {
//初始化状态和结果
this.PromiseState = 'pending'
this.PromiseResult = null
const context = this
//用于存放回调函数
this.callbacks = []
function resolve(value) {
//判断状态是否为pending
if (context.PromiseState !== 'pending') return
context.PromiseState = 'fulfilled'
context.PromiseResult = value
//执行成功的回调函数
setTimeout(() => {
context.callbacks.forEach(element => {
element.onResolved(value)
});
})
}
function reject(reason) {
if (context.PromiseState !== 'pending') return
context.PromiseState = 'fulfilled'
context.PromiseResult = reason
//执行成功的回调函数
setTimeout(() => {
context.callbacks.forEach(element => {
element.onResolved(value)
});
})
}
try {
executor(resolve, reject)
} catch (reason) {
reject(reason)
}
}
//then方法
then(onResolved, onRejected) {
const context = this
return new newPromise((resolve, reject) => {
//封装一个函数
function callback(type) {
//type为onResolved或者onRejected
let result = type(context.PromiseResult)
if (result instanceof newPromise) {
//当返回值是一个Promise对象时,这个对象会再次执行一下then方法
result.then((value) => {
resolve(value)
}, (reason) => {
reject(reason)
})
} else {
resolve(result)
}
}
if (context.PromiseState === 'fulfilled') {
setTimeout(() => {
callback(onResolved)
}, 0)
}
if (context.PromiseState === 'rejected') {
setTimeout(() => {
callback(onRejected)
}, 0)
}
//new Promise()时,里面的异步任务还没有执行完
//故此时状态为pending
if (context.PromiseState == 'pending') {
context.callbacks.push({
onResolved: function () {
callback(onResolved)
},
onRejected: function () {
callback(onRejected)
}
})
}
})
}
-
但是最后的结果是0 1 2 3 4
-
这就证明Promise.then()返回一个Promise对象时,会发起两个微任务队列。
-
至于两个微任务是什么,
-
一个是当返回Promise对象时,这个Promise对象会再次执行一下then方法
-
同时它还会再次隐式开启一个微任务