以下方程式碼為例,我們可以看到詭異的事,最下面外層的 console.log(ary);
竟然回傳的是空陣列,但函式內卻能印出正確的資訊,這是為什麼呢?
let ary = [];
axios.get('https://data.kcg.gov.tw/dataset/6f29f6f4-2549-4473-aa90-bf60d10895dc/resource/30dfc2cf-17b5-4a40-8bb7-c511ea166bd3/download/lightrailtraffic.json')
.then(function (response) {
ary = response.data;
console.log(ary); // [56] 陣列內有56個物件
});
console.log(ary); // [] 空陣列
因為 JavaScript 非同步語法的運作邏輯,是當程式碼運行到 AJAX 語法的時候,它會先發送網路請求到對方的伺服器去,而在等待對方伺服器回傳資料這段期間,AJAX 語法允許在資料還沒回傳到時,程式碼可以繼續往下運行。
等到對方的伺服器回傳資料後,再回來這段程式碼去跑後面的函式
程式碼運行的順序如下圖,因為運行到下方的程式碼時還沒獲得對方伺服器傳來的資訊,所以印出來就會是空的。
等接收到資訊後中間的函式才會運作,才能印出得到的資訊。
為什麼要這樣設計呢?
因為這樣就可以在讓使用者開啟網頁時,不會因為有個需要讀取很久的檔案而卡在中間,如果因為要等某個很大的檔案讀取而讓網頁在開啟時下方呈現一半的空白,這時給使用者的體驗就不太理想。
非同步技術可以讓很大的檔案正在接收的同時先讓使用者看到完整的網頁,等檔案接收到時再呈現在網頁上,使用者可以先看到大部分的網頁內容,使用者的體驗較佳。
但這時就會有疑問,如果不確定何時會接收完資料,如果網頁內容有想要運用該筆資料的資訊的話,該怎麼確保獲得該資料後能被正確操作並且顯示在網頁上?
這時就可以使用函式:
let ary = [];
axios.get('https://data.kcg.gov.tw/dataset/6f29f6f4-2549-4473-aa90-bf60d10895dc/resource/30dfc2cf-17b5-4a40-8bb7-c511ea166bd3/download/lightrailtraffic.json')
.then(function (response) {
ary = response.data;
// 確認接收完資料後再執行下方已註冊的函式
renderData();
});
// 註冊一個函式,此函式內容為想要在網頁上顯示出第一筆資料的日均運量
function renderData(){
const title = document.querySelector('.title');
title.textContent = ary[0]['日均運量'];
}
透過函式的規劃,就可以確保在資料確認接收完後,透過函式去運用該資料並執行我們想要做的事,並且保證後面的程式碼運行不會有問題。
線上課程