要解決的題目以下:面試
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,6chrome
通常遇到Promise.resolve()
時,至關於new Promise(resolve => {resolve()})
都是同步完成的,不會消耗微任務。 但如下狀況時,須要注意,咱們先看三組代碼:瀏覽器
//代碼1
new Promise(resolve => {
resolve(Promise.resolve(4));//resolve了一個Promise
})
.then((res) => {
console.log(res)
})
複製代碼
//代碼2
Promise.resolve().then(() => {
return Promise.resolve(4);//return了一個Promise
})
.then((res) => {
console.log(res)
})
複製代碼
//代碼3
Promise.resolve().then(() => {
return 4;//return了一個Number類型的4
})
.then((res) => {
console.log(res)
})
複製代碼
這三個輸出結果,打印出來的都是數字4。微信
咱們能夠看出不一樣,代碼3是咱們最多見的狀況。代碼3裏打印的res是4
,和上邊return
的是一樣的數據類型。那麼代碼1和代碼2的res爲何不是Object
類型的Promise{<fulfilled>: 4}
呢?markdown
在通常狀況下:函數
Promise.resolve().then(() => {
return 4;
})
複製代碼
這段代碼中,Promise.resolve().then
是一個構造函數,() => {return 4;}
是這個函數的參數,這個函數調用,最後返回一個值爲4
的Promise
(即new Promise(resolve => resolve(4)
).post
而在ui
new Promise(resolve => {
resolve(Promise.resolve(4));//resolve了一個Promise
})
複製代碼
Promise.resolve().then(() => {
return Promise.resolve(4);//return了一個Promise
})
複製代碼
中,由於js在遇到resolve
或者return
一個Promise
對象時,會先求得這個Promise
對象的值,也就是這個Promise
的狀態爲fulfilled
或rejected
的值(假如這個值是'a'
),再用這個值做爲返回的新的Promised
的值,這個新的Promsie
(就是new Promise(resolve => resolve('a')
)做爲下級鏈式調用的Promise
。spa
在chrome內部實現的Promise和標準的Promise/A+規範存在差別。瀏覽器內部實現的區別。咱們能夠理解爲,resolve或者return遇到一個Promise對象時,獲得這個Promise的值以後,會把這個值用微任務包裝起來,在return值向外傳遞(由於後邊沒有.then()了,因此是向父級的外層傳遞)時,會產生第二個微任務。code
因此代碼
//代碼1
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)
})
複製代碼
對應的,代碼
//代碼2
Promise.resolve().then(() => {
return Promise.resolve(4);//return了一個Promise
})
.then((res) => {
console.log(res)
})
複製代碼
能夠理解爲
Promise.resolve()
.then(() => {
return 4;
})
.then()
.then()
.then((res) => {
console.log(res)
})
複製代碼
這樣理解的,和文章開頭的題目結果是一致的,核心就是會比正常的return一個非Promise的值時,多兩個微任務.then().then()
另外的
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)
是同樣的,並不會多產生微任務。由於這兩段代碼的Promsie
狀態變爲fulfilled
的過程並不須要等待。而是拿到它的值以後,在向後運行的時候,會產生微任務。
但若是是
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
才行,
new Promise(resolve => {
resolve(4)
})
.then(res => {
return 4.1
})
.then(res => {
return 4.2
})
複製代碼
自己是會註冊兩個微任務的,而拿到它的值以後,在向後運行的時候,又會產生兩個任務(包裝值一次,return傳遞一次)。
咱們來回顧下文章開頭的題目
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,1,2,3,4,5,6
題目2
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);
})
複製代碼
運行結果爲
題目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
參考文章