一道有意思的题
以下我的进修剖析心路历程,以及我本身又多加了几道菜;愿望对你有协助
先上菜
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
}).then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
}).then(() => {
console.log('then12');
});
剖析第一道菜
- 第一次看到我做错了,答案是
promise1
then11
promise2
then21
then12
then23
- 我的迷惑就是
then12
为何在then21
和then23
之间,很新鲜。申明什么呢?我对Promise
的内部完成还不相识,那只能去看源码了。在进修过程当中,本身也尝试转变了几处,也贴上来吧,人人看看
看完后我的明白
先剖析下面代码
new Promise((resolve, reject) => {
console.log('promise1');
resolve();
})
- 第一步
console.log('promise1')
,这是第一个promise
实例 - 第二步
resolve()
,他是一个异步,放入异步行列中,取名异步1 - 第三步
this.status
状况是pending
接着实行下面代码
.then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve();
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
})
- 由于状况是
pending
,将then要领回调函数到场实行行列(一个数组)守候实行(专用来放then要领的数组),该then
要领取名要领1
重点接着实行什么?
并非实行.then(() => {console.log(then12)})
,要记着的是then
的参数要领实行机遇是当前(属于本身的)promise状况转变才会实行,谁转变resolve或许rejectd的实行
,那末这里then的promise哪里来,就是上面的要领1
中来看他的return值
所以最先实行异步1(我都有取名的,看👆),第一个
promise实例
状况变成FULFILLED
- 起首
resolve()
参数为undefind
不是一个promise范例,所以实行
实行行列(一个数组),即要领1,也就是第一个
then`的参数 - 由于状况转变所以最先实行要领1
() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //新的resolve 取名异步2
}).then(() => {
console.log('then21');
}).then(() => {
console.log('then23');
});
}
- 第一步打印
console.log('then11');
- 又新建了一个
Promise
,打印console.log('promise2');
-
resolve();
又一个异步,放入异步行列中,取名异步2 - 然后由于新的
promise
它的状况是pengding
,所以() => {console.log('then21');}
要领放入新的promise的实行行列的数组中(和上面一样专用来放then要领的数组) - 同理背面的
then
并不回实行,它须要守候新的resolve的实行
,来转变状况实行then
重点2
-
由于要领1的没有return,即return 一个undefined
,但我们都晓得then
会默许返回一个return new Promise((resolve, reject) => {})
对象,所以这时候他是实行了的一个异步操纵resolve()
取名异步3, - 所以有了这个异步3,这个
return
的promise
的状况为pending
,所以then(() => {console.log(then12)})
到场到(专用来放then要领的数组)的实行回调数组中
然后最先实行异步行列的函数,有两个异步2和异步3,先实行异步2,接下来的操纵和重点2
是一样的又会return new Promise((resolve, reject) => {})
,又会有一个异步4resolve()
,接着讲then
要领放入数组中,守候resolve()
转变promise
状况来实行then
要领
- 所以在守候时期会实行
异步3
,然后打印console.log(then12)
- 末了打印
console.log(then23)
总结要点
-
then(func)
实行机遇是守候一个与它相干的promise
的状况转变 -
then(func)
中的func
默许会return new Promise((resolve, reject) => {resolve()})
用于下一个then(func)
- 假如我们手动
return 一个promise
效果就会差别,看下面例子
再变个名堂
new Promise((resolve, reject) => {
console.log('promise1');
resolve(); //异步1
}).then(() => {
console.log('then11');
return new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //异步2
}).then(() => {
console.log('then21');
//默许resolve() 异步3
}).then(() => {
console.log('then23');
//默许resolve() 异步4
});
}).then(() => {
console.log('then12');
});
剖析
- 看到一个
then(func)
中我们直接返回了一个promise
,所以先到场第一异步2,而且要守候它相干的promise状况转变,然则它状况转变了,那就是等异步2的实行,一旦实行,接着就是() =>{console.log('then23'); //默许resolve() 异步4}
的实行了,所以异步4先一步比异步5到场,也就先实行了, - 所以效果就是
promise1
then11
promise2
then21
then23
then12
我再来变个样
new Promise((resolve, reject) => {
console.log('promise1');
resolve(); //异步1
}).then(() => {
console.log('then11');
new Promise((resolve, reject) => {
console.log('promise2');
resolve(); //异步2
}).then(() => {
console.log('then21');
//异步3
}).then(() => {
console.log('then23');
//异步4
});
return Promise.resolve(1) //异步5
}).then(() => {
console.log('then12');
});
剖析一下这几个异步就要能晓得答案了
console.log('promise1');
- 先到场异步1, 实行后输出
console.log('then11');
console.log('promise2');
- 在到场异步2, 再到场异步5
- 先实行异步2,
console.log('then21');
并将到场异步4 - 再实行异步5, 但这个异步和下面的
then
不相干,由于这边隐蔽的会再下到场一个resolve()(即异步6) - 接着先实行异步4, 输出
console.log('then23');
- 接着先实行异步6, 输出
console.log('then12');