问答题1090/1588说说下面代码的输出结果

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)
})
难度:
2023-12-17 创建

参考答案:

输出结果是:

0
1
2
3
4
5
6

1、分析

一般遇到Promise.resolve()时,相当于new Promise(resolve => {resolve()})都是同步完成的,不会消耗微任务。 但以下情况时,需要注意,我们先看三组代码:

1//代码1 2new Promise(resolve => { 3 resolve(Promise.resolve(4));//resolve了一个Promise 4}) 5.then((res) => { 6 console.log(res) 7})
1//代码2 2Promise.resolve().then(() => { 3 return Promise.resolve(4);//return了一个Promise 4}) 5.then((res) => { 6 console.log(res) 7})
1//代码3 2Promise.resolve().then(() => { 3 return 4;//return了一个Number类型的4 4}) 5.then((res) => { 6 console.log(res) 7})

这三个输出结果,打印出来的都是数字4。

我们可以看出不同,代码3是我们最常见的情况。代码3里打印的res是4,和上边return的是同样的数据类型。那么代码1和代码2的res为什么不是Object类型的Promise{<fulfilled>: 4}呢?

在一般情况下:

1Promise.resolve().then(() => { 2 return 4; 3})

这段代码中,Promise.resolve().then是一个构造函数,() => {return 4;}是这个函数的参数,这个函数调用,最后返回一个值为4Promise(即new Promise(resolve => resolve(4)).

而在

1new Promise(resolve => { 2 resolve(Promise.resolve(4));//resolve了一个Promise 3})
1Promise.resolve().then(() => { 2 return Promise.resolve(4);//return了一个Promise 3})

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

2、结论

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

所以代码

1//代码1 2new Promise(resolve => { 3 resolve(Promise.resolve(4));//resolve了一个Promise 4}) 5.then((res) => { 6 console.log(res) 7})

可以理解为

1new Promise(resolve => { 2 resolve(4); 3}) 4.then() 5.then() 6.then((res) => { 7 console.log(res) 8})

对应的,代码

1//代码2 2Promise.resolve().then(() => { 3 return Promise.resolve(4);//return了一个Promise 4}) 5.then((res) => { 6 console.log(res) 7})

可以理解为

1Promise.resolve() 2.then(() => { 3 return 4; 4}) 5.then() 6.then() 7.then((res) => { 8 console.log(res) 9})

这样理解的,核心就是会比正常的return一个非Promise的值时,多两个微任务.then().then()

另外的

1Promise.resolve().then(() => { 2 return Promise.resolve(Promise.resolve(Promise.resolve(4))) 3}) 4.then(res => { 5 console.log(res); 6})

像这样的return Promise.resolve(Promise.resolve(Promise.resolve(4)))嵌套多层Promise,其实和Promise.resolve(4)是一样的,并不会多产生微任务。因为这两段代码的Promsie状态变为fulfilled的过程并不需要等待。而是拿到它的值之后,在向后运行的时候,会产生微任务。

但如果是

1Promise.resolve().then(() => { 2 return new Promise(resolve => { 3 resolve(4) 4 }) 5 .then(res => { 6 return 4.1 7 }) 8 .then(res => { 9 return 4.2 10 }) 11}) 12.then(res => { 13 console.log(res); 14})

这时.then(res => { console.log(res); })想要运行,需要等待前边return 的Promise状态变为fulfilled才行,

1new Promise(resolve => { 2 resolve(4) 3}) 4.then(res => { 5 return 4.1 6}) 7.then(res => { 8 return 4.2 9})

本身是会注册两个微任务的,而拿到它的值之后,在向后运行的时候,又会产生两个任务(包装值一次,return传递一次)。

3、回顾

我们再来看这个题目

1Promise.resolve().then(() => { 2 console.log(0); 3 return Promise.resolve(4); 4}).then((res) => { 5 console.log(res) 6}) 7 8Promise.resolve().then(() => { 9 console.log(1); 10}).then(() => { 11 console.log(2); 12}).then(() => { 13 console.log(3); 14}).then(() => { 15 console.log(5); 16}).then(() =>{ 17 console.log(6); 18})

按照上边的分析,可以对应转化为

1Promise.resolve().then(() => { 2 console.log(0); 3 return 4; 4}) 5.then() 6.then() 7.then((res) => { 8 console.log(res) 9}) 10 11Promise.resolve().then(() => { 12 console.log(1); 13}).then(() => { 14 console.log(2); 15}).then(() => { 16 console.log(3); 17}).then(() => { 18 console.log(5); 19}).then(() =>{ 20 console.log(6); 21})

所以运行结果是0,1,2,3,4,5,6

最近更新时间:2024-07-19

赞赏支持

预览

题库维护不易,您的支持就是我们最大的动力!