核心點
promise在生命周期內有三種狀態,分別是pending,fulfilled或rejected,狀體改變只能是 pending-fulfilled,或者pending-rejected。而且狀態一旦改變就不能再次改變。
題1
promise.resolve()
.then(() => {
console.log('a');
return new Error('error');
})
.then((res)=>{
console.log('b');
console.log('then:',res);
})
.catch((err) =>{
console.log('c');
console.log('catch:',err);
})
可能有些同學會認為出現了 new Error()就會想當然的認為會執行后面的catch函數,其實不然。
在then函數中return了一個Error,依然會按照正常的流程走下去,並不會執行后續的catch函數,這個是不同於thorw拋出一個Error的,如果是throw拋出一個Error則會被catch函數捕獲。
因次答案是:
a
b
c
then:Error : error
題2
const promise = Promise.resolve()
.then(()=>{
return promise;
});
promise.catch(console.error);
結果是
TypeError:Chaining cycle detected for promise #<Promise>
我們需要知道的是Promise的then或者catch里不能返回promise本身,否則會出現死循環,就是上面報的錯誤。
題3
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log);
這個題目主要考察的是在 Promise的then或者catch方法中,接收的是一個函數,函數的參數是resolve或者rejiect函數的返回值,如果傳入的值是非函數,那么就會產生值的穿透現象。
何為值穿透現象,簡單理解就是傳遞的值會被直接忽略掉,繼續執行鏈調用后續的方法。
所以 題3的 答案是 1.
第一個then接受值2 ,第二個接收一個Promise,都不是需要的函數,因此這二個then會發生值穿透。
而第三個then因為接收console.log函數,因此會執行,此時接收的是最開始的resolve(1)的值,因此最后返回 1.
題4
Promise.resolve()
.then(function success(res){
throw new Error('error');
},function faill(e){
console.error('fail1:',e);
})
.catch(function fail2(e){
console.error('fail2',e);
})
在Promise的then方法中,可以接收兩個函數,一個是用於resolve成功的函數,一個是用於reject失敗的函數,兩個函數只會調用一個。我們還可以通過.catch方法去實現then方法中的第二個表示失敗的函數。
但是有一點不同的是.catch方法可以捕獲之前從then方法中拋出的Error,而then方法中的第二個方法捕獲不到第一個處理成功的方法中拋出的Error。
因此我們可以得出這道題目的答案,拋出fail2的Error。
上述的題目可以用下面的代碼去理解
Promise.resolve()
.then(function success1 (res){
thorw new Error('error');
},function() fail1(e){
console.error('fail1',e);
})
.then(function success2(res){},function fail2(e){
console.error('fail2:',e);
})