async await使用以及原理
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div>es6</div>
<script type="text/javascript">
// async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,仅此而已
// async函数返回一个 Promise 对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句
// Generator 函数的执行必须靠执行器,所以才有了co模块,而async函数自带执行器和普通函数一样执行
// async函数对 Generator 函数的改进:
/*
(1)内置执行器
(2)更好的语义
(3)更广的适用性
(4)返回值是 Promise
*/
async function fun() {
try {
return await 123; // 等同于 return 123; 正常情况下,await命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值
} catch (err) {
console.log(err);
}
}
// 只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数
fun().then(res => {
console.log(res, 'res') // 123 "res"
})
async function fn1() {
try {
// 如果有多个await命令,可以统一放在try...catch结构中
const res1 = await 123;
const res2 = await 456;
const res3 = await 789;
// await new Promise(function (resolve, reject) {
// throw new Error('出错了');
// });
console.log(res1, res2, res3) // 先执行 123 456 789
} catch (e) {
// throw new Error('出错了'); // async函数内部抛出错误,会导致返回的 Promise 对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到
}
return await Promise.resolve('hello world');
}
fn1().then(res => console.log(res, 'res2')) // 后执行 hello world res2
// async 函数的实现原理,就是将 Generator 函数和自动执行器,包装在一个函数里。
async function fn(args) {
// ...
}
// 等同于
function fn(args) {
return spawn(function*() {
// ...
});
}
function spawn(genF) {
return new Promise(function(resolve, reject) {
const gen = genF();
function step(nextF) {
let next;
try {
next = nextF();
} catch (e) {
return reject(e);
}
if (next.done) {
return resolve(next.value);
}
Promise.resolve(next.value).then(function(v) {
step(function() {
return gen.next(v);
});
}, function(e) {
step(function() {
return gen.throw(e);
});
});
}
step(function() {
return gen.next(undefined);
});
});
}
</script>
</body>
</html>