iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Modern Web

追求JS小姊姊30天系列 第 29

追求JS小姊姊系列 Day29 -- 方函式的能力展現:最後型態`async`

  • 分享至 

  • xImage
  •  

前情提要:

講述完工具人的起源

方函式:終於到了最後一個能力async模式。
:到現在都遇不到JS...


先知道asyncgenerator使用方式非常相似
generator:用yield控制流程
async:用await控制

兩者差別在於async回傳的是一個Promise物件而不是{value:any,done:Boolean}

如果想基本認識generator的可參考我在D14寫關於生成器的文章

基本認識

async function建構子建立,基本架構為:

//宣告
async function adds(){
    ....;
};

//裝入變數
const x = async function()=>{}

async被呼叫時,會回傳一個Promise物件:

  1. 當回傳一個值,Promise的狀態為resolve,並回傳值。
  2. 當拋出例外或值時,該Promise狀態則為reject並回傳值。

async回傳背後的道理

不知道你會不會好奇,當你呼叫async裡面看起來回傳1,實際上卻是Promise物件,背後是什麼道理。

async回傳1

async function asyncFn(){
    return 1;
}
asyncFn();

是不是會得到相同的結果,原因是當你用async時,它會偷偷幫你轉譯,所以實際上它長得就像是:

function normal(){
    return Promise.resolve(1);
}
normal();

await

數量不限,可寫可不寫

  1. 這個語法只能在async內使用,在async function以外用會syntax error
function hi(){
    await console.log(x);
}
hi()

  1. Promise處理非同步使用
async function add(){
    await setTimeout((x=1)=>console.log(x),20000);
    console.log("x")
}
add()

之所以可以這樣使用,是因為當你使用非Promise的非同步語法時,它會自動將你輸出預設為resolve,並回傳值。

加入awiat就能避免流程被setTimeout卡頓。

  1. Promise都怎麼用呢?
    一般await後面會是new Promise
async function add(){
    await new Promise((resolve,reject)=>{
        resolve("accept");
        reject("deny")
    });
    await new Promise((resolve,reject)=>{
        resolve("accept1");
        reject("deny2")
    });
}
add()

async vs Promise 從可讀性比較

假設你現在有三件事情想依序被執行

Promise
若用Promise,就是透過then()去串連

function a() {
  return new Promise((resolve, reject) => resolve("hi a"));
}

function b() {
  return new Promise((resolve, reject) => resolve("hi b"));
}

function c() {
  return new Promise((resolve, reject) => resolve("hi c"));
}

a()
  .then(function (x) {
    console.log(x);
    return b();
  })
  .then(function (x) {
    console.log(x);
    return c();
  })
  .then((y) => console.log(y));

async

async function hi() {
  let res1 = await new Promise((resolve, reject) => resolve("hi a"));
  let res2 = await new Promise((resolve, reject) => resolve("hi b"));
  let res3 = await new Promise((resolve, reject) => resolve("hi c"));
  console.log(res1);
  console.log(res2);
  console.log(res3);
}
hi();

比較起來,是不是好讀許多呢?

感謝我的隊友幫忙
推推她的文章初學者跪著學JavaScript Day29 : async 和 await

-- to be continued --

一切都要結束了?


那今天就到這邊摟!
每天的休息,是為了後面的追求,明天見。


reference:

MDN
Async & Await


上一篇
追求JS小姊姊系列 Day28 -- 工具人給不完的Promise,`妳`都不要
下一篇
追求JS小姊姊系列 Day30 -- 所以姊姊追到哪了?
系列文
追求JS小姊姊30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
wendy
iT邦新手 2 級 ‧ 2021-10-14 20:34:10

謝謝你的業配,字也太大 笑死

XD 誠意有多大,字就有多大

0
Chiahsuan
iT邦新手 4 級 ‧ 2021-10-14 21:46:54

最後的結局究竟會如何呢?/images/emoticon/emoticon31.gif

XDDDDD 終於到這一天了嗎

我要留言

立即登入留言