10 分钟学会 JavaScript 的 Async/Await

更新日期: 2022-02-09阅读: 845标签: await

前言

在之前很长的一段时间里,JavaScript开发人员不得不依赖回调来处理异步代码。如果遇到赋值的逻辑,会发现,特别难处理维护,代码看起来也特别的糟糕。

值得庆幸的是,后来出现了 Promises,它为回调提供了一种更有条理的替代方案。但是现在,由于 Async / Await 的出现, 编写 JavaScript 代码将变得更好!  

以前我们使用 callback。
后来我们使用 Promise。
现在我们使用 Async/Await。


什么是 Async/Await?

Async / Await是一个备受期待的JavaScript功能,它使异步函数的使用更加愉快和易于理解。它构建在Promises之上,并与所有现有的基于Promise的api兼容。

Async - 定义异步函数(async function someName(){...})

  • 自动把函数转换为 Promise
  • 当调用异步函数时,函数返回值会被 resolve 处理
  • 异步函数内部可以使用 await

Await - 暂停异步函数的执行 (var result = await someAsyncCall();)

  • 当使用在 Promise 前面时,await 等待 Promise 完成,并返回 Promise 的结果
  • await 只能和 Promise 一起使用,不能和 callback 一起使用
  • await 只能用在 async 函数中

下面是一个简单的例子:

假设我们想从服务器上获取一些JSON文件。我们将编写一个使用AXIOS库的函数,并将HTTP GET请求发送到 xxx.json。 我们必须等待服务器响应,所以这个HTTP请求自然是异步的。

下面我们可以看到相同的函数实现了两次。首先是Promise,然后是第二次使用异步/等待。

// Promise
function getJSON(){
    // 为了使函数阻塞,我们手动创建一个Promise。
    return new Promise( function(resolve) {
        axios.get('https://www.javanx.cn/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');

    // GET请求的结果在JSON变量中可用
    // 我们返回它,就像正常同步函数一样
    return json;
}

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

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

那么,Async / Await 会比 Promise更好嘛?

一点都不。使用Async / Await时,我们仍在使用Promise。从长远来看,对Promise的良好理解实际上对您有很大的好处。

甚至有一些用例Async / Await并不能解决问题,我们不得不回到Promise上,需求答案。

一个这样的场景,当我们需要进行多个独立的异步调用并等待所有这些调用完成时。

如果我们尝试使用async和await执行此操作,将发生以下情况:

async function getABC() {
  let A = await getValueA(); // 2 second to finish
  let B = await getValueB(); // 4 second to finish
  let C = await getValueC(); // 3 second to finish

  return A*B*C;
}

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

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

要同时发送所有请求,需要Promise.all()。这将确保执行后面函数之前我们仍然拥有所有结果,但异步调用将并行触发,而不是一个接一个地触发。

async function getABC() {
  // Promise.all()允许我们同时发送所有请求。
  let results = await Promise.all([ getValueA, getValueB, getValueC ]); 
  return results.reduce((total,value) => total * value);
}

这样,该功能将花费更少的时间。 getValueB和getValueC调用将在getValueB结束时完成。我们将有效地将执行时间减少到最慢请求的时间(getValueB - 4秒),而不是时间的总和。


处理Async / Await中的错误

在 Async/Await 语法中,我们可以使用 try/catch 进行错误处理。在 Promise 中的 .catch() 分支会进入 catch 语句。我们只需要像这样包装我们的Await:

async function doSomethingAsync(){
    try {
        // 此异步调用可能会失败.
        let result = await someAsyncCall();
    }
    catch(error) {
        // 我们将在这里发现错误
    }
}

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

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

// 没有try / catch块的异步函数。
async function doSomethingAsync(){
    // This async call may fail.
    let result = await someAsyncCall();
    return result;  
}

// 我们在调用函数时捕获错误
doSomethingAsync().
    .then(successHandler)
    .catch(errorHandler);

根据自己的喜好,选择之中即可。同时使用try/catch和.catch()很可能会导致问题。


浏览器支持


Async / Await已在大多数主流浏览器中提供。排除IE11- 所有其他供应商将识别async/await代码,而无需外部库。


结语

通过添加Async / Await,JavaScript语言在代码可读性和易用性方面取得了巨大的飞跃。编写类似于常规同步函数的异步代码的能力将受到初学者和经验丰富的编码人员的青睐。


链接: https://www.fly63.com/article/detial/11120

理解 Async/await

「async/await」是 promises 的另一种更便捷更流行的写法,同时它也更易于理解和使用。Async functions让我们以 async 这个关键字开始。它可以被放置在任何函数前面,像下面这样

es7中async/await

async/await 是在 ES7 版本中引入的,它对于 JavaScript 中的异步编程而言是一个巨大的提升。它可以让我们以同步的方式处理异步的流程,同时不会阻塞主线程。但是,想要用好这一特性,可能需要动点脑筋

理解使用js中async、await

在讲async之前,先简单的提一下promise。首先,先来纠正一下很多人普遍的错误观点 --> promise是异步的, 看代码:从打印结果来看,我们就可以断定promise是同步的,那么我就说promise是同步的

Js从callbacks到sync/await

好了,关于JavaScript中的异步编程就探讨到这儿,是不是和我们平常采用的Python、Java或C++语言不太一样。有人说,学一门语言,实际上是学习一种编程思路,你没有想到JavaScript会用这种方式来解决异步编程吧

ES7 async/await 的应用

async 函数返回的是一个 Promise 对象,如果在函数中直接 return 一个值,async 会把这个直接量通过 Promise.resolve( ) 封装成 Promise 对象。我们可以通过以下这段代码来说明这个结论:

手写一个async/await的实现

生成器是在定义函数时在function后添加*定义的,像这样:function* func(){},执行生成器函数后会得到一个迭代器,在生成器函数中能支持yield来暂停函数,直到迭代器调用next方法.同时next能传入一个参数来作为yield的值

从 async 和 await 函数返回值说原理

async 和 await 如何工作,如何正确的使用 async 和 await 。async 函数使我们能够编写基于 promise 的代码,就像它是同步的一样,但不会阻塞执行线程。通过事件循环异步运行,async 函数将始终返回一个值。

await、return 和 return await 的陷阱

await、return 和 return await 有很多容易被忽视的不同之处。 await waitAndMaybeReject() 的结果,如果 rejected,我们的 catch 块捕获了异常

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!