Intro

最近在自学CS571,因为现在在上272的缘故便直接跳过了基础的前端语法的讲解,直接从第二课的API Request开始看起

异步请求

API和JSON这种老生常谈的基础概念就不再赘述,一般作请求都会使用异步,在原生JS中有两种方法可以发出请求,XMLHttpRequestfetch

XMLHttpRequest因为比较老了所以不在本次的讨论范围之内,现代JS主要使用fetchfetch是一个promise-based的方法

课上介绍了一些概念

  • Promise:一个带有异步请求是否成功以及请求结果的对象
  • async/await : 用来表示函数是异步的关键字

fetch()

使用异步请求的最基础的写法是如下所示的

1
2
3
4
5
6
7
8
fetch(url)
.then((response) => response.json())
.then((data) => {
console.log("I won't be printed til later");
console.log("Data takes time to fetch");
} )
.catch(error => console.error(error));
console.log("I will print first");

在等待服务器返回的时间,JS会先去做其他事情,比如说输出最后一行的console.log("I will print first");

回调函数 Callback Function

在上面的代码中我们可以发现fetch()后面接了.then().catch()

这两个方法都接受函数作为参数,而这里面的函数也就被称为回调函数

官方的定义如下

A callback function (sometimes called afunction reference) is passed into another function as an argument, which is then invoked inside the outer function to complete a routine or action.

显然,我们可以看出,这样的.then().catch()的代码可读性并不是很高,所有JS引入了async/await

async/await

async/await 的区别

在前面的定义中,我们提到这两个是用来声明异步函数的关键字,但是其用法上存在着区别

  • async 是用来放在函数前,真正用来声明函数是一个异步函数的关键字,并且自动会将函数的返回值包装成Promise
  • await 只能在声明了异步,也就是有 async 的函数内部使用,其作用正如同名字所示,让代码停下来等待,并直接拿到结果

这样写就能够让我们使用我们比较熟悉的try catch捕获网络异常了

将刚刚的代码改造成这种写法就会变成

1
2
3
4
5
6
7
8
9
10
11
async function getApi() {
try{
const response = await fetch(url);
const rawData = await response.json();
console.log("I won't be printed til later");
console.log("Data takes time to fetch");
} catch (error) {
console.error(error);
}
}
console.log("I will print first");

需要注意的是,这段代码里的response拿到的只是一个相应头,必须要在后面的rawData进行解析才能拿到json,同时解析json也要花时间所以也要加上await