10分钟解读 JavaScript Async/Await

简介: 10分钟解读 JavaScript Async/Await

什么是 Async/Await?



Async/Await 是一个期待已久的 JavaScript 特性,它使得使用异步函数变得更加愉快和更容易理解。它建立在 Promises 之上,并与所有现有的基于 promise 的 api 兼容

这个名字来自 async 和 await ——这两个关键词可以帮助我们清理异步代码:


Async-声明一个异步函数(Async function someName (){ ... })


  1. 自动地将一个普通的函数转换成一个承诺
  2. 当调用异步函数时,当异步完成时,然后返回的是异步内容
  3. 在异步函数中允许使用await


Await-暂停 async 函数的执行


  1. 当被放置在一个Promise前时, 强制代码的其余部分等待,直到承诺完成并返回结果
  2. 只对 Promises 起作用,对 callback 不起作用
  3. 只能在里面使用async函数中使用


通过一个简单的例子来分析


假设我们想从服务器获取一些 JSON 文件。我们将编写一个使用 axios 库的函数,并向 https://tutorialzine.com/misc... 发送一个 HTTP GET 请求。我们必须等待服务器响应,所以这个 HTTP 请求自然是异步的


下面我们可以看到同一个函数实现了两个。首先是使用 Promises,然后是第二个使用 Async/Await


// Promise
function getJSON(){
    // 为了使函数阻塞,我们手动创建一个承诺.
    return new Promise( function(resolve) {
        axios.get('https://tutorialzine.com/misc/files/example.json')
            .then( function(json) {
                // 在.then中获得返回的json数据
                // 我们使用resolve返回结果
                resolve(json);
            });
    });
}
// Async/Await
// async关键字将自动创建一个新的Promise并返回它.
async function getJSONAsync(){
    // await关键字使我们不必编写then().
    let json = await axios.get('https://tutorialzine.com/misc/files/example.json');
    // GET请求的结果在json变量中可用.
    // 获取数据就像在一个常规的同步函数中一样
    return json;
}


很明显,Async/Await 版本的代码更短,更容易阅读。除了使用的语法之外,这两个函数完全相同——它们都返回 Promises 并使用 axios 的 JSON 响应解析。我们可以这样调用我们的 async 函数:


async返回本身就是一个Promise


getJSONAsync().then( function(result) {
    // Do something with result.
});


Async/Await 会使承诺过时吗?



不,一点也不。


在使用 Async/Await 时,我们仍然在引擎盖下使用 Promises。


从长远来看,充分理解Promise实际上会对你有所帮助,因此强烈推荐你这么做

甚至在一些情况下 Async/Await 也不能解决问题,我们不得不回到 Promises 寻求帮助。


其中一种情况是,我们需要进行多个独立的异步调用,并等待它们全部完成

如果我们尝试使用 async 和 await 来实现这个功能,将会发生以下情况:


async function getABC() {
  let A = await getValueA(); // getValueA 需要2秒
  let B = await getValueB(); // getValueB 需要4秒
  let C = await getValueC(); // getValueC 需要3秒
  return A*B*C;
}


每个await等待都将等待await前一个返回结果。因为我们一次只调用一个函数,整个函数从开始到结束(2 + 4 + 3)需要9秒


这不是最佳解决方案,因为三个变量 a、 b 和 c 并不相互依赖。换句话说,在得到 b 之前,我们不需要知道 a 的值。我们可以在同一时间得到它们,减少几秒钟的等待时间

在同一时间发送所有请求。这将确保我们在继续之前仍然拥有所有的结果,但是异步调用将并行请求,而不是一个接一个地请求


async function getABC() {
  // Promise.all()允许我们同时发送多个请求,类型是个数组
  let results = await Promise.all([ getValueA, getValueB, getValueC ]); 
  return results.reduce((total,value) => total * value);
}


这样一来,函数运行的时间就会少得多。getValueA 和 getValueC 调用在 getValueB 结束时已经完成,将有效地将执行时间减少到最慢的请求的时间(getValueB-4秒) ,而不是总和


Async/Await 中的错误处理


Async/Await 的另一个优点是,它允许我们在一个很好在 try/catch 块中捕捉任何意外的错误。只需要像这样包装下Await:


async function doSomethingAsync(){
    try {
        // 这里异步可能会发送失败
        let result = await someAsyncCall();
    }
    catch(error) {
        // 如果失败了,通过catch捕捉到错误
    }  
}


Catch 子句将处理等待的异步调用或者我们在 try 块中编写的任何其他失败代码所引发的错误


如果情况需要,我们还可以在执行 async 函数时捕获错误。因为所有的异步函数都返回 Promises,我们可以简单地包含一个。在调用 catch ()事件处理程序时。


async function doSomethingAsync(){
    // This async call may fail.
    let result = await someAsyncCall();
    return result;  
}
// 后面更用catch捕获错误
doSomethingAsync().
    .then(successHandler)
    .catch(errorHandler);


总结



随着 Async/Await 的加入,JavaScript 语言在代码可读性和易用性方面取得了巨大的飞跃。编写类似于常规同步函数的异步代码的能力将受到初学者、 JavaScript 开发者和资深编码者的青睐

相关文章
|
1月前
|
监控 JavaScript 前端开发
确定使用 `defer` 属性还是 `async` 属性来异步加载 JavaScript
【10月更文挑战第24天】选择使用 `defer` 属性还是 `async` 属性来异步加载 JavaScript 是一个需要综合考虑多个因素的决策。需要根据脚本之间的依赖关系、页面加载性能要求、脚本的功能和重要性等因素来进行权衡。在实际应用中,需要通过测试和验证来确定最适合的加载方式,以提供更好的用户体验和页面性能。
|
1月前
|
前端开发 JavaScript 开发者
除了 async/await 关键字,还有哪些方式可以在 JavaScript 中实现异步编程?
【10月更文挑战第30天】这些异步编程方式在不同的场景和需求下各有优劣,开发者可以根据具体的项目情况选择合适的方式来实现异步编程,以达到高效、可读和易于维护的代码效果。
|
1月前
|
JSON 前端开发 JavaScript
浅谈JavaScript中的Promise、Async和Await
【10月更文挑战第30天】Promise、Async和Await是JavaScript中强大的异步编程工具,它们各自具有独特的优势和适用场景,开发者可以根据具体的项目需求和代码风格选择合适的方式来处理异步操作,从而编写出更加高效、可读和易于维护的JavaScript代码。
30 1
|
3月前
|
前端开发 JavaScript 数据库连接
掌握 JavaScript 异步编程:从回调到 Async/Await
在现代 JavaScript 开发中,异步编程是处理非阻塞操作的关键技术。本文从早期的回调函数讲起,逐步过渡到 Promise 和 ES2017 的 async/await 语法,展示了异步编程如何变得更加简洁和强大。通过实用的技巧和最佳实践,帮助开发者避免常见陷阱,提升代码效率和可靠性。
|
2月前
|
JavaScript 前端开发 开发者
掌握Node.js中的异步编程:从回调到async/await
Node.js的异步编程模型是其核心特性之一,它使得开发者能够构建高性能和高并发的应用程序。本文将带你从Node.js的异步编程基础开始,逐步深入到回调函数、Promises、以及最新的async/await语法。我们将探讨这些异步模式的原理、使用场景和最佳实践,并通过实例代码展示如何在实际项目中应用这些概念。
|
2月前
|
前端开发 JavaScript 开发者
JavaScript 中的异步编程:深入了解 Promise 和 async/await
【10月更文挑战第8天】JavaScript 中的异步编程:深入了解 Promise 和 async/await
|
2月前
|
JSON 前端开发 JavaScript
探索JavaScript中的Async/Await:简化异步编程的利器
【10月更文挑战第12天】探索JavaScript中的Async/Await:简化异步编程的利器
21 0
|
2月前
|
前端开发 JavaScript UED
深入了解JavaScript异步编程:回调、Promise与async/await
【10月更文挑战第11天】深入了解JavaScript异步编程:回调、Promise与async/await
21 0
|
7月前
|
JSON 前端开发 JavaScript
【JavaScript技术专栏】JavaScript异步编程:Promise、async/await解析
【4月更文挑战第30天】JavaScript中的异步编程通过Promise和async/await来解决回调地狱问题。Promise代表可能完成或拒绝的异步操作,有pending、fulfilled和rejected三种状态。它支持链式调用和Promise.all()、Promise.race()等方法。async/await是ES8引入的语法糖,允许异步代码以同步风格编写,提高可读性和可维护性。两者结合使用能更高效地处理非阻塞操作。
105 0
|
4月前
|
前端开发 JavaScript 小程序
【JS】async、await异常捕获,这样做才完美
本文通过生动的例子说明了在JavaScript中使用async/await时,不捕获异常可能导致的问题,并介绍了三种处理异步调用异常的方法:try-catch、使用Promise的`.catch`以及`await-to-js`插件库。通过这些方法,可以有效避免异常导致的程序中断,提升代码的健壮性和可读性。
81 0
【JS】async、await异常捕获,这样做才完美