iT邦幫忙

2023 iThome 鐵人賽

DAY 25
0
Modern Web

超低腦容量學習法遇到javascript系列 第 25

這顆語法糖也太好吃了:async & await

  • 分享至 

  • xImage
  •  

用同步程序的寫法來寫非同步程序

看了async和await之後,其實我的內心很是驚訝,這麼平易近人的寫法如果一開始就讓我看見,我大概也不會有精神去搞清楚promise到底在幹嘛吧,恐懼承諾就恐懼承諾,我覺得自己也是可以活的好好的。會有這樣的想法,是因為發現自己對於懂的東西才敢用這件事,好像到了有點歇斯底里的地步,這到底是好還是不好,我一直在問自己,如果只大概知道await是在等一個非同步程序的結果,這個非同步其實會在背景處理,不會卡住主要程式的執行,先用一個變數承接,等它有結果之後,變數自然可以拿來用,如果只知道這樣,我是不是也是可以避著眼睛用?
那麼這顆好吃到驚人的語法糖,到底長怎樣?用之前callback hell寫過的簡單例子,再度改寫成async & await的寫法,因為其實這些await都在micro tasks queue排隊,可以清楚地看出來,數完一秒之後才印出訊息。

function delay(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);
  });
}

async function delayedPrint() {
  await delay(1000);
  console.log("1 sec passed");

  await delay(1000);
  console.log("2 sec passed");

  await delay(1000);
  console.log("3 sec passed");

  await delay(1000);
  console.log("4 sec passed");

  await delay(1000);
  console.log("5 sec passed");
}

delayedPrint();

promise & async await比較

以下用一個例子的兩種不同寫法比較差異,並沒有提供太多自訂函式的細節,只是想單純比較。
promise chaining寫法,先以getLocation()得到目前所在地的座標,並return一個promise,以座標去fetch api獲得相對應的國家與城市,最後以國家名稱再度fetch 另一個api獲得更多國家細節,然後渲染相關的html element。

const whereAmI = function () {
  getLocation()
    .then(result => {
      const { latitude, longitude } = result.coords;
      return fetch(`https://geocode.xyz/${latitude},${longitude}?geoit=json`);
    })

    .then(request => {
      return request.json();
    })
    .then(data => {
      console.log(`You are in ${data.city}, ${data.country}.`);
      return fetch(`https://restcountries.com/v2/name/${data.country}`);
    })
    .then(request => request.json())
    .then(data => renderCountry(data[0]))
    .catch(error => console.error(error))
};

async & await改寫後,能發現這樣的寫法把非同步程序的結果存在變數裡,以供後面的非同步程序使用。

const whereAmI = async function () {
//getLocation()獲得座標,並return一個promise,結果存到locationCoord物件,解構之後得到經緯度
  const locationCoord = await getLocation();
  const { latitude, longitude } = locationCoord.coords;
  
//fetch api將經緯度轉成所在地之國家與城市,回應的結果存在geoRespoinse,再將geoResponse轉成物件
  const geoResponse = await fetch(
    `https://geocode.xyz/${latitude},${longitude}?geoit=json`
  );
  const geoData = await geoResponse.json();
  console.log(`You are in ${geoData.city}, ${geoData.country}.`);
  
//fetch api以獲得country相關的資料,再以renderCountry()函式渲染相關html element
  const countryResponse = await fetch(
    `https://restcountries.com/v2/name/${geoData.country}`
  );
  const countryData = await countryResponse.json();
  renderCountry(countryData[0]);
};

今日總結

async & await寫法只能處理promise chaining裡then的部分,錯誤處理要使用try catch結構來接住各種可能出錯的情境。
至於async & await這樣的語法糖帶來的便利,想想覺得還是要知道promise才好,我想這是因為長久以來的訓練,形成了一種學習與思考問題的風格,我是靠著了解事物的根本來得到成就感與在工作上得到一些些成績的,這也許就像是人的性格,有點天生有點後天養成,可以稍微調整,但因為看到別人作法帶來的好處就否定自己,好像也是太適得其反。

Reference

udemy-The Complete Javascript Course
MDN-json() method


上一篇
承諾恐懼症promise
下一篇
為什麼要try catch
系列文
超低腦容量學習法遇到javascript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言