目录
1. 异步编程和同步编程的区别
同步:代码按照顺序运行,依次执行
异步:代码不按照顺序运行,可以同时执行多个任务
2. 为什么要使用异步编程?
避免阻塞主线程
提高程序性能和响应速度
使程序变得更加可预测和可控
3. async/await基础知识
1. 定义一个异步函数
在函数定义前加上async关键字就可以定义一个异步函数。异步函数返回一个Promise对象,可以使用await操作符等待异步操作的结果,而不必处理回调函数或者Promise的then()和catch()方法。
async function foo() {
// 异步操作
return "result"; // 返回一个Promise对象
}
2. 使用await操作符等待异步操作
在异步函数中,如果需要等待一个Promise对象完成并返回结果,可以使用await操作符。await只能在async函数中使用,它会暂停异步函数的执行,等待Promise对象的结果返回后再继续执行异步函数。
async function foo() {
const result = await bar(); // 等待bar()的异步操作结束并返回结果
// 处理异步操作的结果
// ...
}
3. Promise对象
async/await的核心是Promise对象。如果一个函数返回一个Promise对象,那么async函数就可以使用await操作符等待该Promise对象返回结果。Promise对象表示一个异步操作的最终结果,可以使用resolve方法或reject方法拿到异步操作的结果或错误信息。
function bar() {
return new Promise((resolve, reject) => {
// 异步操作
if (success) {
resolve("result"); // 操作成功,返回结果
} else {
reject("error"); // 操作失败,返回错误信息
}
});
}
4. 错误处理
在异步函数中,可以使用try/catch语句捕获异步操作的错误,并处理错误情况。如果异步操作抛出了错误或者返回了reject状态的Promise对象,那么await操作符会将该错误抛出到异步函数的外部。
async function foo() {
try {
const result = await bar(); // 等待异步操作的结果
// 处理异步操作的结果
// ...
} catch (error) {
// 处理异步操作的错误
// ...
}
}
4. 常见的异步编程模式
1. Callback (回调函数)
Callback是一种异步编程模式,它将一个函数作为参数传递给另一个函数。当异步操作完成时,程序会调用这个函数并将结果作为参数传递给它。
function loadData(callback) {
// 异步操作
setTimeout(function() {
const result = "data";
callback(result);
}, 2000);
}
loadData(function(data) {
// 处理异步操作的结果
console.log(data); // 'data'
});
2. Promise
Promise是ES6提供的一种解决异步编程的模式。Promise可以封装异步操作并返回一个Promise对象,当异步操作完成时,Promise对象会自动调用resolve()方法并返回结果。如果异步操作失败,Promise对象会调用reject()方法并返回错误信息。
function loadData() {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(function() {
const result = "data";
if (success) {
resolve(result); // 操作成功,返回结果
} else {
reject("error"); // 操作失败,返回错误信息
}
}, 2000);
});
}
loadData()
.then(function(data) {
// 处理异步操作的结果
console.log(data); // 'data'
})
.catch(function(error) {
// 处理异步操作的错误
console.error(error);
});
3. Async/Await
Async/Await是基于Promise的一种异步编程模式,它可以使异步代码更加简洁易读。使用Async/Await,可以使用await操作符等待Promise对象的结果,并处理结果或者捕获错误。
async function loadData() {
try {
const result = await fetchData(); // 等待异步操作的结果
// 处理异步操作的结果
console.log(result);
} catch (error) {
// 处理异步操作的错误
console.error(error);
}
}
loadData();
5. 使用async/await进行异步编程的步骤
1. 将异步操作封装为一个Promise对象
首先需要将异步操作封装为一个Promise对象,Promise对象可以使用resolve()方法返回正常结果,使用reject()方法返回错误信息。Promise对象一旦被创建,即开始执行异步操作。
function loadData() {
return new Promise((resolve, reject) => {
// 异步操作
setTimeout(function() {
const result = "data";
if (success) {
resolve(result); // 操作成功,返回结果
} else {
reject("error"); // 操作失败,返回错误信息
}
}, 2000);
});
}
2. 在async函数中使用await操作符等待异步操作的结果
使用await操作符可以等待异步操作的结果,然后将结果赋值给一个变量。在await操作符所在的语句执行之前,异步操作会一直等待。使用await操作符的语句必须在async函数中执行。
async function loadDataAsync() {
try {
const result = await loadData();
// 处理异步操作的结果
console.log(result);
} catch (error) {
// 处理异步操作的错误
console.error(error);
}
}
3. 处理异步操作的结果和错误
使用try/catch语句捕获异步操作的错误,并在catch语句中处理错误。使用正常的同步操作处理异步操作的结果。
async function loadDataAsync() {
try {
const result = await loadData();
// 处理异步操作的结果
console.log(result);
} catch (error) {
// 处理异步操作的错误
console.error(error);
}
}
loadDataAsync();
5. async/await在项目中的使用
1. 异步请求数据
在前后端分离的项目中,前端常常需要向后端发送异步请求获取数据。这时候可以使用async/await封装异步请求,然后在async函数中使用await关键字等待异步请求的返回结果。
async function getDataFromServer() {
try {
const response = await fetch(url);
const data = await response.json();
// 处理返回的数据
} catch (error) {
// 处理错误
}
}
2. 异步操作多个Promise对象
在实际项目中,可能需要同时进行多个异步操作,这时候就可以使用Promise.all()方法等待多个Promise对象全部完成。在async函数中使用await关键字等待Promise.all()方法的返回结果,然后处理多个异步操作返回的数据。
async function loadData() {
try {
const [data1, data2, data3] = await Promise.all([
fetchData1(),
fetchData2(),
fetchData3()
]);
// 同时处理多个异步操作返回的数据
} catch (error) {
// 处理错误
}
}
3. 使用async/await执行定时任务
在实际项目中,有时候需要执行一些定时任务,常常使用setTimeout或setInterval方法,使用async/await可以更加方便地管理定时任务。在async函数中使用while循环执行任务,并使用await关键字等待指定时间后再次执行任务。
async function run() {
while (true) {
// 定时任务
await sleep(1000); // 等待1s
}
}
function sleep(time) {
return new Promise(resolve => setTimeout(resolve, time));
}