await、async、事件循环
- async、await
- 浏览器进程、线程
- 宏任务、微任务队列
- Promise面试题解析
- throw、try、catch
- 浏览器存储Storage
1. 异步函数
async、await
在函数定义的时候前面添加一个async。
1 | async function foo(){ |
异步函数内部的代码与普通函数一样,默认情况下是同步执行的。
1.1 异步函数的返回值
当异步函数有返回值时:
- 异步函数的返回值相当于被包裹在Promise.reslove中。
1 | async function foo() { |
- 如果异步函数返回的也是一个Promise,那么状态会由Promise决定
1 | async function foo1() { |
- 如果异步函数返回的是一个对象并且实现了thenable,那么就会由then方法来决定。
1 | async function foo2() { |
异步函数返回的是一个Promise。
1.2 异步函数的异常
如果在执行函数代码的时候产生了异常,这个异常不会立即被浏览器处理,会Promise.reject()。(作为Promise.reject传递)
也就是我们可以在返回值调用catch捕获到。
1.3 await关键字的使用
await这个关键字只能在异步函数里面才能使用(ES13里面新增可以在顶层模块使用)
通常使用await的时候,在这个关键字后面跟上一个表达式,这个表达式一般返回一个Promise。
这个await会等待Promise状态变为fulfilled状态之后,才会继续执行下面的代码。
1 | async function foo() { |
await处理连续的异步请求:
1 | function requestData(url) { |
如果在await处理时,Promise返回的是一个reject,
- 那么就会向外抛出异常,我们可以在异步函数的返回值调用catch捕获异常。并且后面的代码不会执行
1 | function requestData(url) { |
- 我们还可以使用try catch 捕获异常
1 | function requestData(url) { |
2. 进程和线程
进程:计算机已经运行的程序,是操作系统管理程序的一种方式
线程:操作系统内能够运行运算调度的最小单位,通常情况下它被包含在进程中。
2.1 浏览器中的JavaScript线程
JavaScript运行是有自己的容器:浏览器和node.js。
JavaScript代码在执行的过程之中都是在一个单独的线程之中执行的,也就是JavaScript在同一时刻内,只能做一件事。
2.2 浏览器的事件循环
JavaScript代码中的一些异步任务 ,并不会直接放在上下文执行栈中,而是会被方法哦浏览器中,将这些事件放到一个事件队列当中,执行到哪一个事件的时候再将该事件放到上下文执行栈中。

2.3 微任务和宏任务
在事件队列中,又分为微任务和宏任务。
为什么要进行区分呢?
事件循环中并非只维护着一个队列,事实上是有两个队列:
- 宏任务队列:ajax、setTimeout、setInterval、DOM监听、UI Rendering等
- Promise的then回调、MutationObserverAPI、queueMicrotask()。
宏任务与微任务的执行顺序:
- 在main script中的代码优先执行(编写在顶层的script代码)
- 在执行任何一个宏任务之前,都会查看微任务队列里面是否还有任务需要执行。
3. 异常
3.1 抛出异常
通过throw抛出异常。
使用throw会中断代码的执行。
1 | function throwErr() { |
这段代码就会抛出一个错误。
throw关键字可以跟上以下几种数据类型:
- 基本数据类型:number、string、Boolean
- 对象类型。
JavaScript中有一个自带的Error类。
Error包含三个属性:
- message:创建Error对象时传入的message()错误信息。
- name :Error的名称,通常和类的名称一致。
- stack:整个Error错误信息,包括函数的调用栈。
Error的子类:(了解)
- RangeError:下标值越界时使用的错误类型
- SyntaxError:解析语法错误时的错误类型
- TypeError:出现类型错误时的错误类型
3.2 异常的捕获
抛出的异常如果不进行捕获,它会继续往上抛出,直到被顶部(window或者global)捕获。
所以一般我们要对异常进行捕获。
使用try catch进行异常捕获。
1 | function foo() { |
最后错误被捕获:

如果代码中有一些必须要执行的代码,我们可以在catch中添加一个finally,finally里面的代码无论如何都会执行。