💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 章节导航 [TOC] ## 介绍 当有很多事情发生时,异步代码很难理解。`async`并且`await`是两个关键字,可以帮助使异步读取更像同步代码。这可以帮助代码看起来更干净,同时保持异步代码的好处。 例如,下面的两个代码块完全相同,它们都从服务器获取信息,处理它并返回一个promise。 ``` function getPersonsInfo(name){ return server.getPeople() .then((people)=>{ return people.find(person =>{return person.name === name}); }) } ``` ``` async function getPersonsInfo(name){ const people = await server.getPeople(); const person = people.find(person =>{ return person.name ===name }); } ``` ## 学习成果 1. How do you declare an`async`function? 2. What does the`async`keyword do? 3. What does the`await`keyword do? 4. What is returned from an`async`function? 5. What happens when an error is thrown inside an`async`function? 6. How can you handle errors inside an`async`function? ## async关键字 该`async`关键字是什么让JavaScript引擎知道你是声明一个异步函数,这是需要使用`await`任何函数内。当声明一个函数时`async`,它会自动返回一个promise,在`async`函数中返回与解析一个promise相同,同样抛出一个错误将拒绝这个promise。 要理解的重要一点时async函数只是语法promises 该async关键字也可以与任何一个功能可以创建使用方式,不同的说:它是有效的使用async功能,随时随地可以使用正常的功能。下面您将看到一些可能不直观的示例,如果你不理解可以完成作业后再回头看 ``` const yourAsyncFunction = async() => { return result; //do something asynchronously and return a promise } ``` ``` anArray.forEach(async(item) =>{ // dom something asynchronously for each item in 'anArray' //one could also use .map here to return an array of promises to use with 'Promise.all()' }) ``` ``` server.getPeople().then(async(people)=>{ people.forEach((person)=>{ //do something asynchronously for each person }); }) ``` ### [await关键字] `await`非常简单:它告诉javascript在继续执行函数之前等待异步操作完成。它就像一个'暂停直到'关键字。该`await`关键字用于从通常使用的函数中获取值`.then()`。您不必`.then()`在异步函数之后调用,只需使用变量为结果赋值`await`,然后就可以像在同步代码中一样使用代码中的结果。 ### [错误处理] 处理`async`函数中的错误非常容易。Promises有`.catch()`处理被拒绝的promises的方法,并且由于异步函数只返回一个promise,你可以简单地调用该函数,并`.catch()`在最后添加一个方法。 ~~~javascript asyncFunctionCall().catch((err) => {console.error(err)}); ~~~ 但还有另一种方式:强大的`try/catch`阻挡!如果要直接在`async`函数内部处理错误,可以`try/catch`像在同步代码中一样使用。 但还有另一种方式:强大的`try/catch`阻挡!如果要直接在`async`函数内部处理错误,可以`try/catch`像在同步代码中一样使用。 ~~~javascript async function getPersonsInfo(name) { try { const people = await server.getPeople(); const person = people.find(person => { return person.name === name }); return person; } catch (error) { // Handle the error any way you'd like } } ~~~ 这样做看起来很麻烦,但这是一种非常简单的方法来处理错误,而不会`.catch()`在函数调用后附加。您如何处理错误取决于您,您使用的方法应该由您的代码编写方式决定。您将了解随着时间的推移需要做些什么。作业还将帮助您了解如何处理错误 ## 实践 还记得Giphy API实践项目吗?(如果没有,您应该返回并完成API课程)。我们将基于promise的代码转换为`async/await`兼容代码。以下是我们开始使用的代码的复习: ``` <script> const img = document.querySelector('img'); fetch('https://api.giphy.com/v1/gifs/translate?api_key=bb2006d9d3454578be1a99cfad65913d&s=cat', {mode: 'cors'}) .then(function(response) { return response.json() }) .then(function(response) { img.serc = response.data.images.original.url }) </script> ``` 由于`await`不适用于全局范围,我们必须创建一个`async`包含我们对Giphy的API调用的函数。 ~~~javascript <script> const img = document.querySelector('img') async function getCats() { fetch('https://api.giphy.com/v1/gifs/translate?api_key=111111&s=cats', {mode: 'cors'}) .then(function(response) { return response.json() }) .then(function(response) { img.src = response.data.images.original.url; }) } </script> ~~~ 既然我们有一个异步的函数,那么我们就可以开始使用promises进行重构`await` ~~~javascript <script> const img = document.querySelector('img') async function getCats() { const response = await fetch('https://api.giphy.com/v1/gifs/translate?api_key=111111&s=cats', {mode: 'cors'}); response.json() .then(function(response) { img.src = response.data.images.original.url; }); } </script> ~~~ 由于`response`仍然是我们`.then()`在开始时传递给块的同一个对象,我们仍然需要使用该`.json()`方法,而该方法又返回一个promise。因为`.json()`返回一个promise,我们可以`await`用来将响应分配给一个变量。 ~~~javascript <script> const img = document.querySelector('img') async function getCats() { const response = await fetch('https://api.giphy.com/v1/gifs/translate?api_key=111111&s=cats', {mode: 'cors'}); const catData = await response.json(); img.src = catData.data.images.original.url; } </script> ~~~ 要使用此功能,我们只需要`getCats()`在代码中调用它。 ~~~javascript <script> const img = document.querySelector('img') async function getCats() { const response = await fetch('https://api.giphy.com/v1/gifs/translate?api_key=111111&s=cats', {mode: 'cors'}); const catData = await response.json(); img.src = catData.data.images.original.url; } getCats(); </script> ~~~ 此代码的行为与上一课中的代码完全相同,重构后看起来有点不同。`async/await`在清理异步的JavaScript代码时,它们是非常有用的工具。重要的的英文要记住`async/await`只是以不同方式写的承诺。做下面的任务,深入了解`async/await`。