原文:https://www.cnblogs.com/zhongmeizhi/p/10634771.html
async await本身就是promise + generator的语法糖。
本文主要讲述以下内容
1、async awiat 实质
2、async await 主要特性
async await 实质
下面使用 promise + generate 实现 async await
// 转换目标 async1
// async function async1() {
// console.log('async1 start');
// await async2();
// console.log('async1 end');
// }
function async1() {
// 将 async 转换成 *,将 awiat 转换成 yield
var awaitInstance = (function* () {
console.log('async1 start');
yield async2();
console.log('async1 end');
})()
// 自动执行 await 及后续代码
// 简单起见,不处理异常情况
function step() {
var next = awaitInstance.next();
// 使用Promise获取 异步/同步 方法的结果,再执行下一步
Promise.resolve(next.value).then(function (val) {
if (!next.done) step();
})
}
step();
// 返回Promise
return Promise.resolve(undefined);
}
async await 特性
1.async 一定会返回 promise
// 案例1: 不设置return
async function fn() {}
fn().then(alert); // alert -> undefined
// 案例2:return非promise
async function f() {
return 1
}
f().then(alert); // alert -> 1
// 案例3: return Promise
async function fn() {
return Promise.resolve(2);
}
fn().then(alert); // alert -> 2
2. async 中代码是直接执行的(同步任务)
console.log(1);
async function fn() {
console.log(2);
await console.log(3)
console.log(4)
}
fn();
console.log(5);
// 打印 1 2 3 5 4
// 为何后面是 3 5 4 ? 往下看
3. await是直接执行的,而await后面的代码是 microtask。
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
// 类似于
async function async1() {
console.log('async1 start');
Promise.resolve(async2()).then(() => {
console.log('async1 end');
})
}
4. await后面代码会等await内部代码全部完成后再执行
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
return new Promise(function(resolve) {
setTimeout(function() {
console.log('sleep 2s');
resolve('do');
}, 2000)
})
}
async1();
// 打印结果
// async1 start -> sleep 2s -> async1 end
5. await 操作符用于等待一个Promise 对象。它只能在异步函数 async function 中使用。参考 MDN
-
语法:[返回值] = await 表达式;
- 表达式:一个 Promise 对象或者任何要等待的值。
- 返回值:返回 Promise 对象的处理结果。如果等待的不是 Promise 对象,则返回该值本身。
-
描述
- await 表达式会暂停当前 async function 的执行,等待 Promise 处理完成。若 Promise 正常处理 (fulfilled),其回调的 resolve 函数参数作为 await 表达式的值,继续执行 async function。
- 若 Promise 处理异常 (rejected),await 表达式会把 Promise 的异常原因抛出。
- 另外,如果 await 操作符后的表达式的值不是一个 Promise,则返回该值本身。
例子(MDN)
如果一个 Promise 被传递给一个 await 操作符,await 将等待 Promise 正常处理完成并返回其处理结果。
function resolveAfter2Seconds(x) {
return new Promise(resolve => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
async function f1() {
var x = await resolveAfter2Seconds(10);
console.log(x); // 10
}
f1();
如果该值不是一个 Promise,await 会把该值转换为已正常处理的 Promise,然后等待其处理结果。
async function f2() {
var y = await 20;
console.log(y); // 20
}
f2();
如果 Promise 处理异常,则异常值被抛出。
async function f3() {
try {
var z = await Promise.reject(30);
} catch (e) {
console.log(e); // 30
}
}
f3();
Promise
Promise参考见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p1 = Promise.resolve('1')
const p2 = p1.then(res=>{ // 1. then后面的函数当作是p1这个Promise对象的回调函数,
// 并且是p1这个Prmoise对象的状态是fullfilled时,这个函数才被执行(等待事件循环)
console.log('res'); // 2. Promise的then函数的返回值仍然是一个Promise对象,既然是Promise对象,那么肯定就有状态,
// 如果这个then函数里面抛出了异常,那么then函数返回的Promise对象就是rejected的状态
})
const p3 = p2.catch(err=>{ // 1. then后面的函数当作是p2这个Promise对象的回调函数,
// 并且是p2这个Prmoise对象的状态是rejected时,这个函数才被执行(等待事件循环)
console.log('err') // 2. Promise的catch函数的返回值仍然是一个Promise对象,既然是Promise对象,那么肯定就有状态,
// 如果这个catch函数里面抛出了异常,那么catch函数返回的Promise对象就是rejected的状态
})
const p4 = p3.then(res=>{
console.log('p3 res');
throw new Error('ex')
})
const p5 = p4.catch(err=>{
console.log('p5 err',err);
})
console.log(p1)
console.log(p2)
console.log(p3)
console.log(p4)
console.log(p5)
console.log(p1 == p2);
console.log(p2 == p3);
console.log(p1 == p3);
</script>
</body>
</html>
new Promise(() => {
console.log('1'); // 这个会打印
}).then(res=>{
console.log('2'); // 这个不会打印
}).catch(err=>{
console.log('3'); // 这个不会打印
})
// 以上没有修改promise的状态, 所以后面的then或catch都没有执行
// 但是注意在vuex中,dispatch的action默认返回Promise,即便不return,也会修改返回的promise对象
终于理清楚了Promise以及async和await https://blog.csdn.net/web13985085406/article/details/123220812