要解决的题目如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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
分析
一般遇到Promise.resolve()
时,相当于new Promise(resolve => {resolve()})
都是同步完成的,不会消耗微任务。
但以下情况时,需要注意,我们先看三组代码:
1 2 3 4 5 6
| new Promise((resolve) => { resolve(Promise.resolve(4)); }).then((res) => { console.log(res); });
|
1 2 3 4 5 6 7 8
| Promise.resolve() .then(() => { return Promise.resolve(4); }) .then((res) => { console.log(res); });
|
1 2 3 4 5 6 7 8
| Promise.resolve() .then(() => { return 4; }) .then((res) => { console.log(res); });
|
这三个输出结果,打印出来的都是数字 4。
我们可以看出不同,代码 3 是我们最常见的情况。代码 3 里打印的 res 是 4,和上边 return 的是同样的数据类型。那么代码 1 和代码 2 的 res 为什么不是 Object
类型的Promise{<fulfilled>: 4}
呢?
在一般情况下:
1 2 3
| Promise.resolve().then(() => { return 4; });
|
这段代码中,Promise.resolve().then
是一个构造函数,() => {return 4;}
是这个函数的参数,这个函数调用,最后返回一个值为 4 的Promise
(即new Promise(resolve => resolve(4)
).
而在
1 2 3
| new Promise((resolve) => { resolve(Promise.resolve(4)); });
|
1 2 3
| Promise.resolve().then(() => { return Promise.resolve(4); });
|
中,因为 js 在遇到resolve
或者return
一个Promise
对象时,会先求得这个 Promise 对象的值,也就是这个 Promise 的状态为fulfilled
或rejected
的值(假如这个值是’a’),再用这个值作为返回的新的Promised
的值,这个新的Promise
(就是new Promise(resolve => resolve('a')
)作为下级链式调用的Promise
。
结论
在 chrome 内部实现的 Promise 和标准的 Promise/A+规范存在差异。浏览器内部实现的区别。我们可以理解为,resolve 或者 return 遇到一个 Promise 对象时,得到这个 Promise 的值之后,会把这个值用微任务包装起来,在 return 值向外传递(因为后边没有.then()了,所以是向父级的外层传递)时,会产生第二个微任务。
所以代码
1 2 3 4 5 6
| new Promise((resolve) => { resolve(Promise.resolve(4)); }).then((res) => { console.log(res); });
|
可以理解为
1 2 3 4 5 6 7 8
| new Promise((resolve) => { resolve(4); }) .then() .then() .then((res) => { console.log(res); });
|
对应的,代码
1 2 3 4 5 6 7 8
| Promise.resolve() .then(() => { return Promise.resolve(4); }) .then((res) => { console.log(res); });
|
可以理解为
1 2 3 4 5 6 7 8 9
| Promise.resolve() .then(() => { return 4; }) .then() .then() .then((res) => { console.log(res); });
|
这样理解的,和文章开头的题目结果是一致的,核心就是会比正常的 return 一个非 Promise 的值时,多两个微任务.then().then()
另外的
1 2 3 4 5 6 7
| Promise.resolve() .then(() => { return Promise.resolve(Promise.resolve(Promise.resolve(4))); }) .then((res) => { console.log(res); });
|
像这样的return Promise.resolve(Promise.resolve(Promise.resolve(4)))
嵌套多层Promise
,其实和Promise.resolve(4)
是一样的,并不会多产生微任务。因为这两段代码的Promise
状态变为fulfilled
的过程并不需要等待。而是拿到它的值之后,在向后运行的时候,会产生微任务。
但如果是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Promise.resolve() .then(() => { return new Promise((resolve) => { resolve(4); }) .then((res) => { return 4.1; }) .then((res) => { return 4.2; }); }) .then((res) => { console.log(res); });
|
这时.then(res => { console.log(res); })
想要运行,需要等待前边 return 的 Promise 状态变为fulfilled
才行,
1 2 3 4 5 6 7 8 9
| new Promise((resolve) => { resolve(4); }) .then((res) => { return 4.1; }) .then((res) => { return 4.2; });
|
本身是会注册两个微任务的,而拿到它的值之后,在向后运行的时候,又会产生两个任务(包装值一次,return 传递一次)。
回顾
我们来回顾下文章开头的题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| 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); });
|
按照上边的分析,可以对应转化为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 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,1,2,3,4,5,6
题目 2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| Promise.resolve() .then(() => { return new Promise((resolve) => { resolve(4); }) .then((res) => { console.log(res, "then4_1"); return 4.1; }) .then((res) => { console.log(res); return 4.2; }); }) .then((res) => { console.log(res, "then4_2"); });
Promise.resolve() .then(() => { console.log(1); }) .then(() => { console.log(2); }) .then(() => { console.log(3); }) .then(() => { console.log(5); }) .then(() => { console.log(6); });
|
运行结果为
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 题目 3 Promise.resolve().then(() => { console.log(0); return Promise.resolve(Promise.resolve(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