async/await 回调地狱解决方案
问题背景
在 js 异步编程中,通过回调函数实现。
当多个异步逻辑间产生顺序或关联逻辑,就会产生回调嵌套(回调地狱),导致代码丑陋且难以阅读,形如:
fetch(function() {
fetch(function() {
// ...
});
});
看了阮一峰老师的文章小结为:早期解决方案是 Promise,将横向代码通过 then 包装为纵向,进一步引出 Generator,而 async/await 即是 Generator 的语法糖。
简单说,回调嵌套问题优化方案,根据时间线整理:
回调嵌套 -> Promise -> Generator(async/await)
使用 async/await 解决回调嵌套问题
看案例 index.html(可保存到本地运行):
<!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
打赏: 微信
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。