文章目录
- 概况
- async
- await
- Promise
- 总结常见问题
概况
- 在ts/js中,async 和 await 是用于简化异步操作的关键字,一般与Promise联用(不理解Promise可以看一下这篇《JS中Promise用法(简要说明)》)。
- 它们的核心作用是让异步代码的写法更接近同步代码的逻辑,同时保持非阻塞特性。
async
- 标记函数为异步函数,自动或者主动返回一个 Promise
当你没有显式定义Promise时就会立即自动返回完成的Promise |
---|
![]() |
当你显式定义Promise时会返回一个根据具体情况变化状态的Promise |
---|
![]() |
返回值自动包装为Promise<泛型>的例子 |
---|
![]() |
await
- 暂停函数执行(即停在await修饰的函数那),直到修饰的调用函数返回的Promise完成
await具有暂停直到修饰函数的Promise变为完成状态才继续执行后续代码的能力 |
---|
![]() |
Promise
- async和Promise是关联的,这里列出来可能的返回类型。
函数返回值 | Promise类型 | 示例 |
---|---|---|
无return语句 | Promise< void > (自动包装) | async function f(){} |
返回类型T(如T为number) | Promise< number > (自动包装) | async function f(){ return 1; } |
返回Promise< T > | Promise< T >(不存在自动包装) | async function f(){ return Promise.resolve(t); //t instanceof T} |
- async修饰的函数,始终返回Promise,那么返回的Promise何时算完成?
状态 | 触发方式1 | 触发方式2 |
---|---|---|
解决(Resolve) | A、【return】函数没报错,正常执行完(返回) | C、调用executor提供的【resolve() 】 |
拒绝(Reject) | B、【throw】函数抛出错误 | C、调用executor提供的【reject()】 |
// A、函数没报错,正常执行完(返回)
async function resolveExample() {return "success"; // 等价于 Promise.resolve("success")// 也可以不需要return
}
// B、函数抛出错误
async function rejectExample() {throw new Error("failed"); // 等价于 Promise.reject(error)
}
// C、调用executor提供的两个函数类型的参数resolve, reject
async function timeout(delay: number) {return new Promise((resolve, reject) => { //executor提供的两个函数类型的参数resolve, rejectif (delay < 0) {reject("Invalid delay");} else {setTimeout(() => resolve("Timeout done"), delay);}});
}
总结常见问题
- Q:await可以处理什么值?
- A:用来处理Promise的,但是可以是任何值,因为就算不是Promise,也会自动包装为Promise
- Q:对于一个函数,await可以单独出现吗?
- A:要想函数体内部使用await,必须用async修饰函数(否则报错)。
- Q:async修饰的函数,返回值是什么?
- A:任何标记为 async 的函数,无论内部是否包含 await(其实返回值和await没有关系),始终返回 Promise。
- Q:async修饰的函数,没有显式返回Promise时会发生什么?
- A:自动将函数返回值包装为一个立即解决的 Promise。
- Q:通过 await 调用的函数,必须返回 Promise 吗?
- A:不是必须,但强烈建议。(被调函数如果显式返回Promise则解决了再执行后续,没有返回则自动包装一个立即解决的Promise)
- Q:如果一个async函数A,函数A的内部仅仅只有一行代码,通过await 调用了一个函数B,问通过变量C接收函数A返回的Promise对象,Promise对象是怎么样的?
- A:如果函数B调用了resolve(),变量C是一个undefined的结果(因为没有任何return,所以是自动包装了个undefined); 如果函数B调用了reject(),此时变量C是一个和函数B一样的Promise状态(可以理解为继承了内部的没有捕获的异常状态); 如果给函数B调用的地方增加了try catch捕获异常,哪怕是函数B调用了reject(),变量C得到的是一个undefined的Promise结果(因为没有任何return,所以是自动包装了个undefined),这里可以得出,只要async函数A正常执行完毕,就算没有return,都会返回一个undefined结果的Promise。