因为JavaScript是一种单线程的语言,无法同时执行多个任务。为了解决这个问题,JavaScript引入了Promise和async/await两种方式来处理异步操作。
Promise是一种用于处理异步操作的对象,它可以将异步操作包装成一个对象,通过链式调用的方式来处理异步操作的结果。Promise对象有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。当异步操作执行完成后,Promise对象的状态会从pending变为fulfilled或rejected,并且会调用相应的回调函数。
而async/await是ES2017引入的一种用于处理异步操作的语法糖,它是基于Promise的一种更加简洁和可读性更高的异步编程模式。,它基于Promise实现,使得异步代码的编写更加简洁和易读。async函数是一个返回Promise对象的函数,通过在函数前面加上关键字async来声明。在async函数中,可以使用await关键字来等待一个Promise对象的结果,然后将结果赋值给一个变量。
一、Promise
Promise是一种用于处理异步操作的对象。它有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。一个Promise对象可以通过调用resolve方法来转为fulfilled状态,或者通过调用reject方法来转为rejected状态。当一个Promise对象的状态变为fulfilled或rejected时,会触发相应的回调函数。Promise 是 ES6 中引入的一种处理异步操作的方式,它通过 then 和 catch 方法来处理异步操作的结果和错误。
Promise的基本用法如下:
const promise = new Promise((resolve, reject) => {
// 异步操作
if (异步操作成功) {
resolve(结果);
} else {
reject(错误);
}
});
promise.then((结果) => {
// 处理成功的结果
}).catch((错误) => {
// 处理失败的错误
});
Promise 的构造函数接受一个执行器函数作为参数,该执行器函数接受两个参数 resolve 和 reject,分别用于处理异步操作的结果和错误。Promise的优点是可以避免回调地狱(callback hell),即多层嵌套的回调函数。但是在处理多个异步操作时,Promise的链式调用会导致代码冗长且难以维护。这时可以使用async/await来简化代码。
二、async/await
async/await是基于Promise的一种更加简洁和可读性更高的异步编程模式。async函数是返回一个Promise对象的函数,而await关键字用于等待一个Promise对象的结果。
在使用async/await时,我们可以使用try/catch语句来捕获和处理异步操作中的错误。try/catch可以用于捕获await表达式中的错误,以及async函数内部的同步错误。如果在async函数内部没有使用try/catch来捕获错误,错误会被自动地传递给async函数返回的Promise对象的拒绝处理函数。
async函数的基本用法如下:
async function 函数名(参数) {
// 异步操作
if (异步操作成功) {
return 结果;
} else {
throw 错误;
}
}
函数名(参数).then((结果) => {
// 处理成功的结果
}).catch((错误) => {
// 处理失败的错误
});
在async函数中,可以使用await关键字来等待一个Promise对象的结果。await关键字只能在async函数中使用,它会暂停async函数的执行,直到Promise对象的状态变为fulfilled或rejected。
await关键字的基本用法如下:
const 结果 = await Promise对象;
await关键字只能在async函数内部使用,它用于等待一个Promise对象的解析结果。当遇到await关键字时,async函数会暂停执行,直到Promise对象被解析完成并返回结果。
注意,await关键字只能在async函数中使用。如果在非async函数中使用await关键字,会导致语法错误。
async/await的优点是可以使用同步的方式编写异步代码,使得代码更加简洁和易于理解。它可以避免回调地狱,同时也可以处理多个异步操作的并发执行。
三、async/await和Promise的区别
async/await和Promise都是用于处理异步操作的方式,它们之间有以下几点区别:
-
语法差异:async/await使用async函数和await关键字来处理异步操作,而Promise使用Promise对象的then和catch方法来处理异步操作。
-
错误处理:在async/await中,可以使用try/catch语句来捕获异步操作的错误。而在Promise中,可以使用catch方法来捕获异步操作的错误。
-
可读性:使用Promise时,由于需要通过链式调用的方式来处理异步操作的结果,代码会变得比较冗长,可读性较差。而使用async/await时,可以通过在async函数中使用await关键字来等待异步操作的结果,代码更加简洁和易读。async/await相对于Promise来说,代码更加简洁和易于理解。它使用同步的方式编写异步代码,避免了回调地狱。
-
并发执行:Promise可以使用Promise.all方法来并发执行多个异步操作,而async/await需要使用Promise的语法来实现。
-
使用场景:Promise适用于处理多个异步操作的情况,可以通过链式调用的方式来处理异步操作的结果。而async/await适用于处理单个异步操作的情况,通过在async函数中使用await关键字来等待异步操作的结果。
四、实例演示
- 使用Promise实现异步操作
function delay(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
delay(1000).then(() => {
console.log('1秒后执行');
});
- 使用async/await实现异步操作
async function delay(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function run() {
await delay(1000);
console.log('1秒后执行');
}
run();
- 并发执行多个异步操作
使用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); // [1, 2, 3]
});
使用async/await实现:
async function run() {
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.resolve(3);
const results = await Promise.all([promise1, promise2, promise3]);
console.log(results); // [1, 2, 3]
}
run();
五、总结
async/await 和 Promise 是 JavaScript 中处理异步操作的两种方式。async/await 是基于 Promise 的语法糖,它可以更方便地编写异步代码。在使用 async/await 时,可以使用 try/catch 语句来处理异步操作的错误。在使用 Promise 时,可以使用 then 和 catch 方法来处理异步操作的结果和错误。
async/await是基于Promise的一种更加简洁和可读性更高的异步编程模式,可以避免回调地狱,使得代码更加简洁和易于理解。
如果只需要处理一个异步操作,可以使用Promise;如果需要处理多个异步操作,可以使用async/await和Promise的组合来实现并发执行。
原文链接:https://juejin.cn/post/7330143281525571638 作者:前端fighter