async/await 回调地狱解决方案

2023-10-22 15:57:23 浏览数 (2)

问题背景

在 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

0 人点赞