Andy的前後端技術筆記、生活紀錄
Javascript中的promise - 處理異步
發佈於: 2023-03-23 更新於: 2024-04-21 分類於: frontend

promise是幹嘛的?

promise這個方法是ES6時推出的,這個主要可以用來解決非同步中XMLHttpRequest的問題
promise不需要監測Event(也就是js中的addEventListener()),而且會在資料回傳時執行callback function,
以及處理在做非同步請求時使用callback時所產生的callback hell。
之所以會產生callback hell是因為,當多個非同步請求有前後相關性時就會發生,所謂的前後相關性就是C request 需要等到
B request的結果才能發出請求,B又要等到A request的結果才能發出,這樣就會變成巢狀的結構,會變得非常難以閱讀。

示意:
1
2
3
4
5
6
7
8
9
callback(()=>{
//在此發出A request
callback(()=>{
//在此發出B request
callback(()=>{
//在此發出C request
})
})
})

callback hell

Promise有什麼?

如前面提到promise是用來處理異步事件,promise會有三個狀態

  • pending : 等待,還沒接到對方的資料回傳,等待中也就是Not Available
  • fulfilled : 成功,也就是有資料成功回傳一個值,在這情況下會進入 .then
  • rejected : 失敗,對方(可能是server)回傳一個錯誤 會進入catch處理錯誤。

舉例

1
2
3
4
5
6
7
8
9
10
11
const getCountryData = (country)=>{
fetch(`https://restcountries.com/v2/name/${country}`).then((res)=>{
return res.json();
}).then((data)=>{
console.log(data);
}).catch(()=>{
console.log('error');
})
}

getCountryData('taiwan');

上述例子使用fetch去執行異步向某個server發出資料請求,並在then裡面等待回傳資料,若是回傳錯誤會由catch處理錯誤
fetch是一個可以回傳promise的function,而在then裡面經常需要處理資料,而資料經常是JSON格式,若要轉譯JSON格式則必須使用json()這個function,但因為它也是回傳promise,所以必須再透過then處理。

如何解決callback hell?

如果會有前後相依的fetch要做,也就是需要等到前一個fetch取得資料後才執行,可以如下,在then裡面 return fetch,如此就可以在後面的then繼續處理第二個fetch的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const getCountryData = (country)=>{
fetch(`https://restcountries.com/v2/name/${country}`).then((res)=>{
return res.json();
}).then((data)=>{
console.log(data);
return fetch(`https://restcountries.com/v2/name/china`)
}).then((res)=>{
return res.json()
}).then((data)=>{
console.log(data);
}).catch(()=>{
console.log('error');
})
}

getCountryData('Taiwan');

不過此法雖然解決callback hell,但是then也變得很長,接下來又有async/await來讓其進化

--- 到底拉 The End ---