TypeScript中的 async 的用法
typescript 中,异步函数 async 是一种特殊类型的函数,它可以返回一个 Promise 对象。异步函数使用 async 关键字声明,并使用 await 关键字等待 Promise 对象的完成。
typescript 中,异步函数 async 是一种特殊类型的函数,它可以返回一个 Promise 对象。异步函数使用 async 关键字声明,并使用 await 关键字等待 Promise 对象的完成。
下面详细记录一下 typescript 中的异步函数用法
什么是异步函数?
在 ts 中,如果使用 async function 定义一个函数,那么这个函数就是异步函数,这点和 python 很像
function normal() {
return 123;
}
async function asyncFn() {
return 123;
}什么是 Promise
Promise 是一个用于处理异步操作的对象,表示一个“未来才会有结果的值”。它有三种状态:
| 状态 | 描述 |
|---|---|
pending | 等待中(未完成) |
fulfilled | 已成功完成 |
rejected | 已失败 |
对于一个耗时的操作,如网络请求,本地 IO 操作,可以不阻塞整个进程
定义一个返回 Promise 对象的函数
async function asyncFn(r:boolean=true): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(r){
resolve('Async Function Result');
}else{
reject('Error occurred in Async Function');
}
}, 1000);
});
}一般有两类结果
- 成功使用 resolve(xxx) 返回
- 失败使用 reject(xxx) 返回,这个 reject 的效果相当于抛了一个异常
也可以直接返回数据,如
async function asyncFn() {
return 123;
}这种看似返回了 123, 但其实是返回的是 Promise<number>
async function test() {
return 123
}
const result = test();
console.log(result);上面代码输出Promise { 123 }
普通函数也可以返回 Promise 对象
一个普通的 function 函数,也是可以返回一个 Promise 对象的
function test2() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(123)
}, 1000);
}
);
}如何调用 async 函数?
如果直接调用一个异步函数,无论是 async function 定义的,还是普通的 function 函数,但是返回的是 Promise 对象,都将会得到一个 Promise { <pending> }
async function asyncFn(r:boolean=true): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(r){
resolve('Async Function Result');
}else{
reject('Error occurred in Async Function');
}
}, 1000);
});
}
async function test() {
return 123
}
function test2() {
return new Promise((resolve) => {
setTimeout(() => {
resolve(123)
}, 1000);
}
);
}
async function main() {
const t1 = asyncFn()
const t2 = test()
const t3 = test2()
console.log('t1', t1)
console.log('t2', t2)
console.log('t3', t3)
}
main();上面的输出为
t1 Promise { <pending> }
t2 Promise { 123 }
t3 Promise { <pending> }并不能正常的得到函数运行的结果
如何获得异步的执行结果呢? 有以下几种方式
1、使用 await
使用 await
async function main() {
const t1 = await asyncFn()
const t2 = await test()
const t3 = await test2()
console.log('t1', t1)
console.log('t2', t2)
console.log('t3', t3)
}await 需要在 async function 函数中
使用 await 方式调用异步函数时,如果 Promise 返回的是 reject,则会报错,相当于其他语言里的 exception,所以经常配合 try 一起使用
async function asyncFn(r:boolean=true): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
if(r){
resolve('Async Function Result');
}else{
reject('Error occurred in Async Function');
}
}, 1000);
});
}
async function main() {
try{
const r = await asyncFn(false);
console.log(r);
}catch(e){
console.error(e);
}
}
main()2、使用 .then .catch
这个是传统的写法
async function main() {
asyncFn(false).then(result=>{
console.log('Result:', result);
}).catch(error=>{
console.error('Caught Error:', error);
});
// 下面的代码并不需要等待上面的代码执行结束再执行
test2().then(result=>{
console.log('Test2 Result:', result);
});
}使用 then 的方式,可以不必写在 async 函数里。
3、使用一个匿名的 async 调用
因为使用 await 需要在 async 函数中调用,所以这会引出一系列的问题,将原本不是 async 的函数改为 async ,那么整个函数调用链都需要修改,下面这种提供了一中匿名调用,依然使用 await ,但是不用写在 async 函数里
在不能使用 await 的地方(比如普通函数或全局作用域),通过创建一个临时 async 函数来使用 await。
function main() {
(async()=>{
try{
const res1 = await asyncFn(false);
console.log(res1)
}catch(err){
console.error(err)
}
})();
}
main();无论那种方式,其实都是对于 Promise 对象结果的获取