Fetch 與 Promise (五):async 與 await


Posted by s103071049 on 2021-07-10

同步的缺點是某一行如果需要比較多秒,畫面就會凍結,直到那一行執行完成。但 async 與 await 可以克服上面的麻煩,讓畫面不被凍結。讓我用同步的語法,背後卻是非同步的跑。

這個函式是非同步的,如果裡面要用 await,外面一定要用 async 包住。

const sleep = ms =>
  new Promise( (resolve, reject) => setTimeout(resolve, ms))
async function main() {
  console.log('enter main')
  await sleep(500)
  console.log('exit main')
}
main()

// 用 promise 的寫法
function mainPromise() {
  console.log('enter main')
  sleep(500).then(() => {
    console.log('exit main')
  })
}

await 後面接 promise 才會有 promise 的效果。它會等 promise 執行完畢才到下一行。


fetch 會把資料拿回來

const api200 = 'https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0'
fetch(api200)
  .then((response) => {
    return response.json()
  }).then(json => {
    console.log(json)
  }).catch(err => {
    console.log('err', err)
  })

簡化代碼,將 fetch 包成一個 function。fetch 會回傳一個 promise,所以我的 function 就直接 return 這個東西,故執行 function 就會拿到這個 fetch 的 promise。

function getData() {
  const api200 = 'https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0'
  return  fetch(api200)
    .then((response) => {
    return response.json()
  })
}

下面可以接 .then() 拿到原本的資料

const request = getData()
request.then(data => {
  console.log(data)
})

甚至也不用宣告變數,直接 getData().then

利用 await, async 看起來像同步的寫法去做非同步的事情。

function getData() {
  const api200 = 'https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0'
  return  fetch(api200)
    .then((response) => {
    return response.json()
  })
}

async function main() {
  console.log('enter main')
  await(1000) // 等一秒,發 request 才秀結果
  const result = await getData() // 等它,呼叫 function 拿到 promise
  console.log('result', result) // 拿到 result {test: "okok"}
}
main()

利用這個寫法,錯誤處理就可以使用原本的 try catch

async function main() {
  console.log('enter main')
  await(1000) // 等一秒,發 request 才秀結果
  try {
    const result = await getData() // 等它,呼叫 function 拿到 promise
  } catch(err) {
    console.log('錯誤', err)
  }
  console.log('result', result) // 拿到 result {test: "okok"}
}

重點回顧

使用 async 與 await 可以用很像同步的方式寫代碼,但底層是非同步,可讀性大大提高,因為沒有甚麼 .then 或 .catch 的東西,就是基本的 function call。

唯一差別,這個 function call 會回傳一個 promise。要回傳 promise,才能用 async, await 語法達成這件事情。

getData return 是 undefined。

function getData() {
  const api200 = '1https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0'
  fetch(api200) // 直接這樣沒有用,因為沒有回傳 promise。
    .then((response) => {
    return response.json()
  })
}
async function main() {
  console.log('enter main')
  await(1000)
  try {
    const result = await getData() // getData 沒有回傳任何東西
    console.log('result', result) 
  } catch(err) {
    console.log('錯誤', err)
  }
  console.log('result', result) // 拿到 result {test: "okok"}
}
main()

.then 完 .cath 完 回傳的結果都是 promise,將 promise return 回去

function getData() {
  const api200 = '1https://run.mocky.io/v3/c3eca63b-2cbd-4b74-bdab-ccc32767c7d0'
  return fetch(api200)
    .then((response) => {
    return response.json()
  })
}

#async 與 await







Related Posts

筆記:所有的函式都是閉包:談 JS 中的作用域與 Closure

筆記:所有的函式都是閉包:談 JS 中的作用域與 Closure

 [ 筆記 ] Express 04 - 工具安裝懶人包

[ 筆記 ] Express 04 - 工具安裝懶人包

簡明程式解題入門 - 陣列篇 IV

簡明程式解題入門 - 陣列篇 IV


Comments