问题背景
在 js 异步编程中,通过回调函数实现 当多个异步逻辑间产生顺序或关联逻辑,就会产生回调嵌套(回调地狱),导致代码丑陋且难以阅读,形如:
代码语言:javascript复制fetch(function() {
fetch(function() {
// ...
});
});
从附录中阮一峰老师的文章中得出: 早期解决方案是 Promise,可以将横向代码通过 then 包装为纵向 更近一步的引出 Generator,而 async/await 即是 Generator 的语法糖
简单说,回调嵌套问题优化方案,根据时间线整理为: 回调嵌套 -> Promise -> Generator(async/await)
使用 async/await 解决回调嵌套问题
看案例 index.html(可保存到本地运行):
代码语言:javascript复制<!DOCTYPE html>
<html>
<head>
<title>Async/Await Example</title>
</head>
<body>
<script>
function callapi(v) {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://h.lukachen.work/api.php?arg=' v, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr.statusText);
}
}
};
xhr.send();
});
}
async function run() {
try {
var res1 = await callapi(1);
console.log(res1);
var resObject = JSON.parse(res1)
var res2 = await callapi(resObject.data);
console.log(res2);
} catch (error) {
console.log(error);
}
}
run();
</script>
</body>
</html>
上述案例中,两次 callapi,第二次使用了第一次的返回值
await 方法阻塞当前行代码直到异步响应完成,使得异步代码可以用同步的写法,摆脱了回调嵌套问题
附录
阮一峰老师针对 async、Generator、Promise 做了比较详细的解释 http://www.ruanyifeng.com/blog/2015/05/async.html https://www.ruanyifeng.com/blog/2015/04/generator.html