Async/await有时被称为Promises之上的 "语法糖"。但这到底是什么意思?答案其实很简单:Async/await实际上只是引擎盖下的promises,但有不同的(有人会说更简单)语法。
让我们使用一个非常常见的承诺的例子:获取数据。
用承诺获取数据
我们将首先使用浏览器内置的fetch 函数。当你把一个URL传给fetch ,它返回一个承诺。一旦该承诺与响应一起解析,我们就可以对该响应使用.json() 方法来返回另一个承诺。该承诺将与请求响应的json体进行解析。
下面是所有这些从GitHub公共API中获取用户数据的动作。
fetch('https://api.github.com/users/nas5w')
.then((res) => res.json())
.then((data) => {
console.log(data);
})
.catch((err) => {
console.error(err);
});
/*
{
"login": "nas5w",
"id": 7538045,
"node_id": "MDQ6VXNlcjc1MzgwNDU=",
"avatar_url": "https://avatars2.githubusercontent.com/u/7538045?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/nas5w",
"html_url": "https://github.com/nas5w",
"followers_url": "https://api.github.com/users/nas5w/followers",
"following_url": "https://api.github.com/users/nas5w/following{/other_user}",
"gists_url": "https://api.github.com/users/nas5w/gists{/gist_id}",
"starred_url": "https://api.github.com/users/nas5w/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/nas5w/subscriptions",
"organizations_url": "https://api.github.com/users/nas5w/orgs",
"repos_url": "https://api.github.com/users/nas5w/repos",
"events_url": "https://api.github.com/users/nas5w/events{/privacy}",
"received_events_url": "https://api.github.com/users/nas5w/received_events",
"type": "User",
"site_admin": false,
"name": "Nick Scialli",
"company": null,
"blog": "http://www.twitter.com/nas5w",
"location": "Washington, DC",
"email": null,
"hireable": null,
"bio": "Husband, dog dad, software engineer, and data science enthusiast.\r\n",
"twitter_username": null,
"public_repos": 44,
"public_gists": 1,
"followers": 249,
"following": 5,
"created_at": "2014-05-09T21:05:01Z",
"updated_at": "2020-11-28T15:41:35Z"
}
*/
很好,如果你对承诺很熟悉的话,这可能是很简单的。
添加异步等待
由于async/await仍然使用承诺,我们可以使用同样的例子我喜欢认为async/await的方式是,我们告诉我们的解释器,一个函数是异步的(async),在该函数中,我们将等待(await)一个承诺(或多个承诺)的解决,然后继续前进。
让我们看看我的意思。
// This is an asynchronous function
async function getGithubData() {
// Let's wait for the promise returned from fetch to resolve
const res = await fetch('https://api.github.com/users/nas5w');
// Let's wait for the promise returned from res.json() to resolve
const data = await res.json();
// Now we have our data, let's log it
console.log(data);
}
你可能会注意到,如果你试图运行这个,什么也不会发生!这是因为我们把它藏在了一个小盒子里。这是因为我们把这段代码塞进了一个异步函数中*,但*我们从未调用过那个函数。我们可以继续调用它,我们应该得到和以前一样的控制台输出。
getGithubData();
这下好了现在还有最后一步:我们需要处理任何错误通过承诺,我们能够使用承诺.catch 方法。有了async/await,我们将用try/catch块来包装一切。
async function getGithubData() {
try {
const res = await fetch('https://api.github.com/users/nas5w');
const data = await res.json();
console.log(data);
} catch (err) {
console.error(err);
}
}
getGithubData();
现在你已经将一个承诺转换为async/await的语法了!