Day.30 「什麽!? Promise 的语法糖?」 —— ES8 Async & Await

「什麽!? Promise 的语法糖?」 —— ES8 Async & Await

ES8 新增了 asyncawait 两个语法,这两个语法也是为了更方便解决非同步的语法,可以说是 Promise then 的语法糖。

async

async 的使用方法,是在要使用的函式前面加上,如: async function fn(){},而它的回传值为 Promise 物件。

async function fn() {
  return "我成功了!"
}
const result = fn();
console.log(result);

Promise 物件

可以看的出来是 Promise 物件,return 的资料会在 [[PromiseResult]] 里,而 fulfilled 代表正确执行完

但正常来说,我们不会把资料写死,我们通常会 return 一个新的 Promise 用来判断成功或失败

同样我们可以使用 thencatch 来抓成功或失败的资料

async function fn() {
  return new Promise((res, rej) => {
    if("达成条件") {
      res("成功")
    } else {
      rej("失败")
    }
  })
}

const result = fn();

result.then( data => {
  console.log(data);
}).catch( err => {
  console.warn(err);
})

await

光看 async 可能还感觉不优点,当学完 await 後,就会觉得原来还可以这麽简单!

  • await 必须要放在 async 函式内
  • 通常右边表达式会衔接 Promise 物件
  • await 返回的是 Promise 成功的值
  • await 的 Promise 失败了,就会抛出异常,可以通过 try{}catch(){} 处理

获取到成功的值

const p = new Promise((res, rej) => {
  res("成功");
})

async function fn(){
  let result = await p;  // 接收 Promise 返回成功的值
  console.log(result);
}

fn();  // "成功"

通过 try{}catch(){} 获取到失败的值

const p = new Promise((res, rej) => {
  rej("失败");
})

async function fn(){
  try {
    let result = await p;  // 接收 Promise 返回成功的值
    console.log(result);
  } catch(err) {
    console.warn(err);
  }
}

fn();  // "失败"

运用在 AJAX 上

AJAX 是 Asynchronous JavaScript and XML 的缩写,也是前端必学的技能,由於 AJAX 技术比较复杂,没办法三言两语的快速介绍,本篇会着重在 asyncawait 运用上。

先来包装 AJAX 请求

function sendAJAX (url) {
  return new Promise((res, rej) => {  // Promise 包装
    const xml = new XMLHttpRequest();  // 创建 XML 物件
    xml.open("GET", url);  // GET 请求
    xml.send();  // 发送
    xml.onreadystatechange = function(){
      if( xml.readyState === 4 ) {  // 读取处理阶段
        if( xml.status >= 200 && xml.status < 300){  // 状态码
          res(xml.response);  // 成功
        } else {
          rej(xml.status);    // 失败
        }
      }
    }
  })
}

包装好了我们就可以使用 AJAX,这里使用政府提供的 动物认领养的 API 进行串接

先使用 then 方法来实作

const ANIMAL_URL = "https://data.coa.gov.tw/api/v1/AnimalRecognition/"

sendAJAX( ANIMAL_URL ).then( data => {
  console.log(data);  // 可以获取到 JSON 档案
}, err => {
  console.warn(err);
})

在来使用 asyncawait 来实作看看

async function fn(){
  try {
    let result = await sendAJAX( ANIMAL_URL );  // 接收 AJAX
    console.log(result);
  } catch(err) {
    console.warn(err);
  }
}
fn();    // 可以获取到 JSON 档案

一样也能实现想要的效果,虽然这里看不出来优势,但如果是要接收复数的 AJAX,asyncawait 会更加方便一些

async function fn(){
  try {
    let result = await sendAJAX( ANIMAL_URL );   // 接收领养动物 AJAX
    let weather = await sendAJAX( WEATHER_URL ); // 接收天气预报 AJAX
    console.log(result);
  } catch(err) {
    console.warn(err);
  }
}
fn();    // 可以获取到 JSON 档案

总结

学会了 asyncawait 後,配合 axios 套件,简直太方便了!

完赛心得

终於完赛 30 天铁人赛了!一路下来有点抖,原本有预先囤两篇文章做缓冲,结果中秋连假一个不小心把扣打消耗掉一篇,於是後面每天都在赶隔天的文章,想着如何介绍才能有趣易懂!

这次的文章安排,其实都是在补足我个人学习还不太了解或面试可能会问的地方,所以文章学的内容可能会跳太快~

果然 30 天要把前端技能塞好塞满,还是有点心有余而力不足呀,也很意外没想到还有人会订阅我的文章,真是太感动了!

很幸运的是能遇到愿意跟我组队的团队,是在参加六角学院活动时,临时起意组成的团队,虽然没有什麽交集,但有跟人一起参与铁人赛就更有动力,夥伴都在努力撑了,我怎麽能轻言放弃呢!

在此谢谢各位观看我的文章,我有利用 Hexo 套件新建自己的 部落格,欢迎大家来参观,近期可能不会出新文章,不过应该会把 旧笔记 翻新後放在部落格上,而我要继续赶我的 Side Project 了~

毛毛在此下台一鞠躬!我们明年铁人赛见~


<<:  Day30 撒花~

>>:  Day24 让你的k8s Pod 具备多介面功能 - 实做篇

EP28 - 使用 Container Insights 监控 EKS 上的容器,并整合 Grafana 作为仪表板

在 EP25 和 EP26, 我们为 EKS 配置了 Grafana 和 Loki, 让我们可以透过...

[Day2] - 前端,後端是在做什麽?

近几年有在经营程序学习的读书会,其中有些问题是大家常会询问的问题,而前端/後端要在做什麽就是一个热门...

Day 19 - SwiftUI开发学习3(Stack 、 Scroll View、Stepper)

昨天学了toggle,今天学stack以及如何做切换页面。 正文 stack stack用来排版用的...

拆掉 v-model + computed get/set 到 vuex

为什麽要特别写 Form 表单攻略呢? 因为这是使用者可以输入资料的常见途径,一种可以「写入」资料的...

[Day 27] 所以说那个手机版

Grid 还是 Flex 我们回归到行动装置本身,究竟我们在前端设计的时候,要采用 Grid 还是 ...