前一篇提到一個重要原則:非同步任務都要記得回傳 promise。除了有利於鏈接,也避免一些錯誤。
像這個例子中有 promise 但沒有回傳,後面的處理函式就無法再追蹤到它的結果,也就是說這個 promise 變成是 'floating' 的狀態。
/* 這是錯誤示範 */
doSomething()
.then((url) => {
// 這裡忘了回傳
fetch(url);
})
.then((result) => {
// result 為 undefined
});
另外,如果沒有回傳 promise,後面的處理函式不會等待,可能導致抓到不正確的結果。
/* 這是錯誤示範 */
const listOfIngredients = [];
doSomething()
.then((url) => {
// 這裡忘了回傳
fetch(url)
.then((res) => res.json())
.then((data) => {
listOfIngredients.push(data);
});
})
.then(() => {
// 這個 then 不會等前面,所以會一直得到 []
console.log(listOfIngredients);
});
上面第二個錯誤示範可以改寫成兩種寫法:
const listOfIngredients = [];
doSomething()
.then((url) =>
fetch(url)
.then((res) => res.json())
.then((data) => {
listOfIngredients.push(data);
})
)
.then(() => {
console.log(listOfIngredients);
});
// 或
doSomething()
.then((url) => fetch(url))
.then((res) => res.json())
.then((data) => {
listOfIngredients.push(data);
})
.then(() => {
console.log(listOfIngredients);
});
兩者差別在於第一個把 fetch
那段鏈接寫成巢狀,第二個把所有的鏈接都寫在第一層。為免模糊焦點,兩者的比較在後面 error handling 再寫,這邊就是強調 then handler 有 output 要回傳,並且可以養成習慣碰到非同步都回傳 promise。