JavaScript Async / Await在10分钟内解释

在最长的时间里,JavaScript开发人员不得不依赖回调来处理异步代码。
结果,咱们中的许多人都经历过回调地狱...

谢天谢地,而后(或者咱们应该说 .then)来了Promises。他们为回调提供了更有组织的替代方案,而且大多数社区很快转而使用它们。如今,随着最新添加的Async / Await,编写JavaScript代码即将变得更好!

什么是async/await?

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

  1. 自动将常规函数转换为Promise;
  2. 当被调用的异步函数解析为它们体内返回的内容时;
  3. 异步功能可使用await

await - 暂停执行异步功能。(var result = await someAsyncCall();)

  1. 当置于Promise调用以前时,await强制其他代码等待Promise完成并返回结果;
  2. Await仅适用于Promises,它不适用于回调;
  3. Await只能在 async 函数内部使用

下面一个简单的例子,但愿可以解决问题:
javascript

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

咱们将看到两次执行相同的功能。首先使用Promise,而后第二次使用Async / Await
java

// Promise

function getJSON(){

    // 建立一个Promise
    return new Promise( function(resolve) {
        axios.get('https://tutorialzine.com/misc/files/example.json')
            .then( function(json) {
                // 请求的数据用resolve返回结果
                resolve(json);
            });
    });

}

// Async/Await 

// async关键字将自动建立并返回 Promise
async function getJSONAsync(){
    // wait关键字使咱们没必要编写.then()块
    let json = await axios.get('https://tutorialzine.com/misc/files/example.json');
    // 请求的结果赋值给json变量并返回
    return json;
}复制代码

很明显,代码的Async / Await版本更短,更容易阅读。除了使用的语法以外,两个函数彻底相同 - 它们都返回Promises并使用axios的JSON响应来解析。咱们能够像这样调用咱们的异步函数:

getJSONAsync()。thenfunction(result) {
     //用result作一些事情。 
});复制代码

Async / Await是否会使Promise过期

不会。使用Async / Await时,咱们仍在使用Promise。甚至有一些用例Async / Await没有削减它,咱们不得不回到Promises寻求帮助。一个这样的场景是当咱们须要进行多个独立的异步调用并等待全部这些调用完成时。ios

若是咱们尝试使用async和await执行此操做,将发生如下状况:

async function getABC() {
  let A = await getValueA(); // getValueA须要2秒才能完成
  let B = await getValueB(); // etValueB须要4秒才能完成
  let C = await getValueC(); // getValueC须要3秒才能完成

  return A*B*C;
}复制代码

每一个等待调用将等待前一个返回结果。因为咱们一次只进行一次调用,整个功能从开始到结束须要9秒(2 + 4 + 3)。

这不是一个最佳的解决方案,由于这三个变量 AB以及 C不依赖于彼此。换句话说,咱们不须要知道 A以前的价值 B。咱们能够同时得到它们而且等待几秒钟。要在同一时间发送全部请求, Promise.all()则须要。这将确保在继续以前咱们仍然拥有全部结果,但异步调用将并行触发,而不是一个接一个地触发。

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子句将处理由等待的异步调用或咱们可能在try块内写入的任何其余失败代码引起的错误。
json

若是状况须要,咱们还能够在执行异步函数时捕获错误。由于全部异步函数都返回Promise,因此在调用它们时咱们能够简单地包含一个.catch()事件处理程序。
axios

// 没有try / catch块的异步函数

async function doSomethingAsync(){
    // 此异步调用可能会失败
    let result = await someAsyncCall();
    return result;  
}

// 在调用该函数捕获错误。
doSomethingAsync().
    .then(successHandler)
    .catch(errorHandler);复制代码

选择你喜欢的错误处理方法并坚持下去是很重要的。同时使用try/catch和.catch()极可能会致使问题。浏览器

浏览器支持

Async / Await已在大多数主流浏览器中提供。这仅排除IE11 - 全部其余供应商将识别您的异步/等待代码,而无需外部库。


                                                         异步/等待浏览器支持bash


参考文献:tutorialzine.com/2017/07/jav…服务器

相关文章
相关标签/搜索