英文 | https://medium.com/frontend-canteen/10-code-challenges-to-master-promise-then-and-promise-catch-3da2bdea1d97
前面,我們要讨論了 Promise 在異步程式設計中的執行,錯過的朋友可以直接點選《10 個 JavaScript Promise 的面試題》這篇文章進行檢視。
在今天的文章中,我們将讨論這些核心 API 用于 Promise 對象的用法。
這裡我提供了10個代碼片段,你需要看一看這些程式的執行結果。
你準備好了嗎?我們要開始了!
01、
const promise = new Promise((resolve, reject) => {
resolve("success1");
reject("fail");
resolve("success2");
});
promise
.then(res => {
console.log("then: ", res);
}).catch(err => {
console.log("catch: ", err);
})
此代碼段的輸出是什麼?
分析
我們知道 Promise 可能是以下三種狀态之一:
- 待定:初始狀态,既不履行也不拒絕。
- 已完成:表示操作已成功完成。
- 拒絕:表示操作失敗。
狀态隻能從待處理變為已完成,或從待處理變為已拒絕。
這種變化是不可逆的。它不能從已完成變為待處理,也不能從拒絕變為待處理。同時,完成不能變成拒絕,拒絕也不能變成完成。
是以在上面的代碼中,隻有 resolve('success1') 是一個有效的操作。最後兩個無效。
結果
這是嵌入示範:
const promise = new Promise((resolve, reject) => {
resolve("success1");
reject("fail");
resolve("success2");
});
promise
.then(res => {
console.log("then: ", res);
}).catch(err => {
console.log("catch: ", err);
});
02、
const promise = new Promise((resolve, reject) => {
reject("fail");
resolve("success2");
});
promise
.then(res => {
console.log("then1: ", res);
}).then(res => {
console.log("then2: ", res);
}).catch(err => {
console.log("catch: ", err);
}).then(res => {
console.log("then3: ", res);
})
此代碼段的輸出是什麼?
分析
首先,無論catch方法放在哪裡,都能捕捉到上層沒有捕捉到的錯誤。
同時需要注意的是,catch 方法也會傳回一個新的 Promise 對象,導緻後面的 then 方法也被執行。
結果
是以輸出是:
catch: fail
then3: undefined
03、
Promise.resolve(1)
.then(res => {
console.log(res);
return 2;
})
.catch(err => {
return 3;
})
.then(res => {
console.log(res);
})
.then(res => {
console.log(res);
});
此代碼段的輸出是什麼?
分析
每個 .then() 方法的傳回值都是一個新的 Promise。即使代碼說 return 2,實際執行的是 return Promise.resolve(2) 。
結果
是以輸出是:
1
2
undefined
04、
Promise.reject(1)
.then(res => {
console.log(res);
return 2;
})
.catch(err => {
return 3;
})
.then(res => {
console.log(res);
})
.then(res => {
console.log(res);
});
此代碼段的輸出是什麼?
分析
這個挑戰和上一個幾乎一樣,隻是從 Promise.resolve 變成了 Promise.reject。是以執行流程會有一些變化。
結果
是以輸出是:
3
undefined
05、
const promise = new Promise((resolve, reject) => {
resolve(1)
})
promise.then(res => {
console.log('first then: ', res)
return 2
})
promise.then(res => {
console.log('second then: ', res)
return 3
})
promise.then(res => {
console.log('third then: ', res)
})
此代碼段的輸出是什麼?
分析
記住一條鐵律:一旦确定了 Promise 的狀态,就無法更改。
同樣在這個題中,那些 .then() 不是鍊式調用,它們都是對 promise 對象的調用。
結果
是以輸出是:
1
1
1
06、
Promise.resolve().then(() => {
return new Error('error!!!')
}).then(res => {
console.log("then: ", res)
}).catch(err => {
console.log("catch: ", err)
})
此代碼段的輸出是什麼?
分析
小心這個挑戰。
new Error() 是一個普通的 JavaScript 對象,return 是一個普通的 JavaScript 關鍵字,是以這段代碼會正常工作,不會抛出異常。
它将傳回一個已完成狀态且值為 new Error('error!!!') 的對象。
是以輸出是:
then: Error: error!!!
當然,如果你想抛出錯誤,你可以使用以下任一方法:
return Promise.reject(new Error('error!!!'));
// or
throw new Error('error!!!')
07、
const promise = Promise.resolve().then(() => {
return promise;
})
promise.catch(console.err)
此代碼段的輸出是什麼?
分析
.then 或 .catch 傳回的值不能是 Promise 本身,否則會導緻死循環。
是以代碼會抛出異常:
TypeError: Chaining cycle detected for promise #<Promise>}
08、
Promise.resolve(1)
.then(2)
.then(Promise.resolve(3))
.then(console.log)
此代碼段的輸出是什麼?
分析
這個問題看似簡單,但其實大部分人的答案都是錯誤的。
- .then 或 .catch 的參數應該是一個函數。
- 如果參數不是函數,則此 .then 或 .catch 将被忽略。
總結
以上就是我今天跟你分享的全部内容,希望這個内容對你有所幫助,最後,感謝你的閱讀。