关于字节一道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

一、分析一下

1.1 基础知识

Promise.resolve()等价于下面的写法。
Promise.resolve('foo')
// 等价于
new Promise(resolve => resolve('foo'))

1.2 分析过程

Promise.resolve().then(() => {
    console.log(0);
    return Promise.resolve(4);
}).then((res) => {
    console.log(res)
})

//结果是:4

那么如果:

console.log( Promise.resolve(4) );

//结果为:Promise{<fulfilled>: 4}

为什么会造成在这种结果?return Promise.resolve(4);为什么是4,不是Promise{<fulfilled>: 4}呢?

1.3 分析结论

因为js在遇到resolve或者return一个Promise对象时,会先求得这个Promise对象的值,也就是这个Promise的状态为fulfilled或rejected的值(假如这个值是'a'),再用这个值作为返回的新的Promised的值,这个新的Promsie(就是new Promise(resolve => resolve('a'))作为下级链式调用的Promise。

二、结论

new Promise(resolve => {
    resolve(Promise.resolve(4));//resolve了一个Promise
})
.then((res) => {
    console.log(res)
})

可以理解为:

new Promise(resolve => {
    resolve(4);
})
.then()
.then()
.then((res) => {
    console.log(res)
})
结论:在chrome内部实现的Promise和标准的Promise/A+规范存在差异。浏览器内部实现的区别。我们可以理解为,resolve或者return遇到一个Promise对象时,得到这个Promise的值之后,会把这个值用微任务包装起来,在return值向外传递(因为后边没有.then()了,所以是向父级的外层传递)时,会产生第二个微任务。

三、回到题目中

开头题目中的写法:

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);
})

可以转换成:

Promise.resolve().then(() => {
    console.log(0);
    return 4;
})
.then()
.then()
.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
  • 文章阅读量133

相关文章

暂无相关文章

联系小鹿线

咨询老师

咨询老师

扫码下载APP