在很长一段时间里,JavaScript 开发人员不得不依赖回调来处理异步代码。所以,咱们中的许多人都经历过回调地狱,当面对这样的函数时,咱们会感到无赖javascript
不过好在JavaScript提供了,.then()的一种回复方式,目前也有不少人正在用他java
如今,随着 Async/Await 的最新增长,编写 JavaScript 代码将会变得更加优雅!ios
Async/Await 是一个期待已久的 JavaScript 特性,它使得使用异步函数变得更加愉快和更容易理解。它创建在 Promises 之上,并与全部现有的基于 promise 的 api 兼容json
这个名字来自 async 和 await ——这两个关键词能够帮助咱们清理异步代码:axios
Async-声明一个异步函数(Async function someName (){ ... })api
Await-暂停 async 函数的执行数组
假设咱们想从服务器获取一些 JSON 文件。咱们将编写一个使用 axios 库的函数,并向 https://tutorialzine.com/misc... 发送一个 HTTP GET 请求。咱们必须等待服务器响应,因此这个 HTTP 请求天然是异步的promise
下面咱们能够看到同一个函数实现了两个。首先是使用 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 时,咱们仍然在引擎盖下使用 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 的另外一个优势是,它容许咱们在一个很好在 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 开发者和资深编码者的青睐
文章属于翻译,做者:羊先生
英文原文