一、async
、await
、Promise
使用介绍
当然!在 TypeScript 中,Promise
的使用可以涉及多个方面,包括基础用法、类型系统、异步操作的错误处理以及高级用法等。下面我会详细讲解这些内容。
1. Promise
的基本概念
Promise
是一种用于处理异步操作的对象。它代表了一个在未来可能完成的操作及其结果。基本的 Promise
状态有:
- Pending(进行中): 初始状态,操作尚未完成。
- Fulfilled(已成功): 操作完成,结果成功。
- Rejected(已失败): 操作完成,结果失败。
2. 创建和使用 Promise
创建 Promise
一个 Promise
对象由一个执行器函数(executor function)初始化,该函数接受两个参数:resolve
和 reject
。
const promise = new Promise<number>((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true; // 假设这是某个条件的结果
if (success) {
resolve(42); // 成功,返回值为 42
} else {
reject(new Error('Something went wrong')); // 失败,返回错误
}
}, 1000);
});
使用 Promise
可以使用 then
和 catch
方法来处理 Promise
的结果或错误。
promise
.then(result => {
console.log('Result:', result); // Output: Result: 42
})
.catch(error => {
console.error('Error:', error.message);
});
3. TypeScript 的类型系统与 Promise
TypeScript 允许你指定 Promise
的类型,这样可以让你在编译时得到类型检查。
function fetchNumber(): Promise<number> {
return new Promise<number>((resolve, reject) => {
setTimeout(() => {
resolve(123);
}, 1000);
});
}
在这个例子中,fetchNumber
函数返回一个 Promise<number>
。这意味着当 Promise
完成时,它将返回一个 number
类型的结果。
4. async
和 await
async
和 await
是处理 Promise
的语法糖,使得异步代码看起来像是同步的。在JavaScript中,async和await是用于处理异步操作的关键字。它们通常一起使用,以简化异步代码的编写和读取。
async
函数
async
关键字用于定义一个异步函数,异步函数总是返回一个 Promise
对象。即使你在 async
函数中返回一个普通值,它也会被包装成一个 Promise
。在async函数内部,可以使用await关键字等待Promise的完成。
async function getNumber(): Promise<number> {
return 123; // 实际上返回的是 Promise.resolve(123)
}
await
关键字
await
关键字只能在 async
定义的异步函数中使用。它会暂停 async
函数的执行,直到 Promise
被解决或拒绝。await
表达式的值就是Promise resolve
的结果。
async function main() {
try {
const number = await getNumber();
console.log(number); // Output: 123
} catch (error) {
console.error('Error:', error);
}
}
main();
5. 异常处理
在异步代码中处理错误非常重要。你可以使用 try
/catch
语句来捕获 async
函数中的错误,或者在 Promise
链中使用 catch
方法。
async function fetchData(): Promise<number> {
return new Promise<number>((resolve, reject) => {
// 模拟错误
setTimeout(() => reject(new Error('Failed to fetch data')), 1000);
});
}
async function main() {
try {
const data = await fetchData();
console.log(data);
// 这里的data是一个`Promise`对象
} catch (error) {
console.error('Error:', error.message); // Output: Error: Failed to fetch data
}
}
main();
使用Promose
链中的catch
方法捕获错误信息
async function fetchData():Promise<number>{
return new Promise<number>((resolve,reject) => {
setTimeout(() => reject(new Error('Failed to fetch data')), 1000);
})
}
async function main(){
featchData().then(res=>{
// 这里的`res`resolve中返回的参数
console.log(res);
}).catch((e)=>{
console.log("error",e);
})
}
6. Promise.all 和 Promise.race
有时你可能需要处理多个 Promise
。Promise.all
和 Promise.race
是两个有用的方法。
Promise.all
: 接受一个Promise
数组,当所有Promise
都完成时,它返回一个新的Promise
,其结果是所有Promise
的结果组成的数组。如果任何一个Promise
失败,则返回的Promise
也会失败。
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
Promise.all([promise1, promise2, promise3])
.then(results => {
console.log(results); // Output: [1, 2, 3]
})
.catch(error => {
console.error('Error:', error);
});
Promise.race
: 接受一个Promise
数组,返回一个新的Promise
,该Promise
会在第一个Promise
完成或失败时完成。
const p1 = new Promise<number>((resolve) => setTimeout(() => resolve(1), 500));
const p2 = new Promise<number>((resolve) => setTimeout(() => resolve(2), 100));
Promise.race([p1, p2])
.then(result => {
console.log(result); // Output: 2 (因为 p2 先完成)
});
7. 其他高级用法
Promise.allSettled
Promise.allSettled
接受一个 Promise
数组,返回一个新的 Promise
,其结果是每个 Promise
的状态和结果组成的数组。
const p1 = Promise.resolve(1);
const p2 = Promise.reject(new Error('Failed'));
const p3 = Promise.resolve(3);
Promise.allSettled([p1, p2, p3])
.then(results => {
console.log(results);
/*
Output:
[
{ status: 'fulfilled', value: 1 },
{ status: 'rejected', reason: Error: Failed },
{ status: 'fulfilled', value: 3 }
]
*/
});
二、async
、await
、Promise
实际应用
1. 在请求接口中使用Promise
2. 在需要等待执行的函数中使用Promsie
3. 在需要等待加载的方法中使用
import JSZip from 'jszip'
import shp from 'shpjs'
const parseZip = async(zip)=>{
const jsZip = new JSZip() // 解析zip数据为二进制数据
const zipData = await jsZip.loadAsync(zip)
const data = await zipData.generateAsync({ type: 'arraybuffer' }) // 将zip文件转化为二进制流
return await shp(data) // 将二进制流转换为geojson数据
}
三、 总结
TypeScript 中的 Promise
提供了一种强大的方式来处理异步操作。通过利用 TypeScript 的类型系统和 async
/await
语法,可以使异步代码更易于理解和维护。掌握 Promise
的各种方法和用法将帮助你编写更健壮和可维护的异步代码。如果你有更多问题或需要深入探讨,请告诉我!