做出有序列的ajax call
callback hell
經過前一章的練習,可以知道非同步請求的特性就是你無法預測哪一個資料會顯抵達,像是我是用巢狀的setTimeout回調函式,才能照想要的順序把發出的ajax call所得到的資料,照我想要的順序得到並且顯示
可是缺點就是,總不能為了讓ajax call有序列,就設計讓setTimeout一直巢狀下去吧?眼睛容易花~~
為什麼會使用callback fn/回呼函式?
回呼函式是當我們想做有序列的ajax calls時(意思是發送ajax非同步請求時,要讓伺服器送回來的資料按照我想要的順序收到)
有時候,舉前一章的練習來說,如果我有這樣的需求:
1.我想要先發送取得“葡萄牙”這個國家1的相關資料並顯示,
2.然後再依據收到的“葡萄牙”的資料來去發送第二個ajax call請求:幫我找“葡萄牙”鄰國的資料西班牙/ESP(在rest countries有另外提供以國家縮寫/${code}的api連結)
因此,這樣代表要得到第二筆資料是仰賴第一筆資料的先抵達!才會需要做呈現有順序排隊回來ajax call請求,流程大概是這樣,來進入程式碼~
程式碼總覽:
- 目前只做先搜尋第一個國家的程式碼,把程式碼依據功能拆開,渲染功能的函式renderCountry拉出來,因為待會會重複使用
- 然後getCountryAndNeighbout這個函式就是主力,透過api提供的窗口/網址讓我們發出ajax call取得資料
切分來看程式碼:
使用者故事&開發功能流程
- 我想要,當我呼叫getCountryAndNeighbout('portugal')可以得到葡萄牙國家的資料並且顯示出來,同時還會自動帶出葡萄牙鄰近國家的資料一起顯示出來
- 我想要,當我呼叫getCountryAndNeighbout('use')可以得到美國國家的資料並且顯示出來,同時還會自動帶出美國鄰近國家的資料一起顯示出來
這個就代表getCountryAndNeighbout我們可能要設計成得到主要國家的資料後,再度依據這個國家1的資料得到鄰近國家的資料,然後發出第二個ajax call取的鄰近國家的詳細資料,並顯示出來
程式碼:
因為渲染的函式都是跟上面一樣內容,就沒有再放圖片了
發出第二個ajax call程式碼分析:
顯示:
當我改成呼叫getCountryAndNeighbour('usa');
顯示:
真的就這樣找到鄰國資料了!!
但是,仔仔細細看一下getCountryAndNeighbour這個函式,ajax call是巢狀的寫在這個函示裡,load事件也是重複做,如果今天需要更多相關連的資料,那就不是要把ajax call巢狀下去.....程式深深深幾許?這就是callback hell回呼地獄
callback hell 回呼地獄
當需要的資料越來越多,發送多筆ajax call若要按照上面的方式來做序列的呈現,我們的程式碼就會一直出現無限的巢狀callback fn,這就是所謂的回呼地獄
程式碼變得很亂,很難閱讀與維護
這也是為什麼有出現ES6 promise 出現來挽救callback hell 的情況