我正在学习Javascript ES2017 async / await功能。已经阅读了很多关于它的内容,并且发现了等待就像收益的理解,并允许我们等待承诺完成。
来自https://javascript.info/async-await
async function showAvatar() {
// read our JSON
let response = await fetch('/article/promise-chaining/user.json');
let user = await response.json();
// read github user
let githubResponse = await fetch(`https://api.github.com/users/${user.name}`);
let githubUser = await githubResponse.json();
// show the avatar
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
// wait 3 seconds
await new Promise((resolve, reject) => setTimeout(resolve, 3000));
img.remove();
return githubUser;
}
showAvatar();
我的问题是,我可以添加等待每一行代码吗?或者,如果我删除单词等待会发生什么?
另一个问题是,如果async / await使得代码似乎同步并按顺序运行,为什么我们根本不使用它(意味着让一切都保持同步?)
谢谢!
async
函数只是Promises的语法糖。它没有任何改变功能是同步的。事实上,任何async
函数都会隐式返回一个Promise
对象。
所有await
都提供了等待Promise的便捷方式。如果删除await
关键字,那么Promise
将不会被“解包”,如果你的函数将对Promise的结果进行操作,那么这不是你想要的。
为了说明,这是您的异步函数的desberared版本:
function showAvatar() {
let githubUser;
// read our JSON
return fetch('/article/promise-chaining/user.json').then(response => {
return response.json();
}).then(user => {
// read github user
return fetch(`https://api.github.com/users/${user.name}`);
}).then(githubResponse => {
return githubResponse.json();
}).then(user => {
githubUser = user;
// show the avatar
let img = document.createElement('img');
img.src = githubUser.avatar_url;
img.className = "promise-avatar-example";
document.body.append(img);
// wait 3 seconds
return new Promise((resolve, reject) => setTimeout(resolve, 3000));
}).then(() => {
img.remove();
return githubUser;
});
}
所以await
基本上只是添加了一个.then
回调给Promise。如果没有指定await
,你将只拥有一个Promise对象,而不是Promise的结果。
await
告诉运行时等待从右侧的表达式返回的promise将被实现。
在下面的代码中,在异步函数中停止控制,直到满足fetch
调用返回的promise,并将发送到履行的promise的响应值打印到控制台。
async function go() {
let response = await fetch('http://www.example.com');
console.log(response); // print the response after some time
}
go();
如果省略了await关键字,那么控制将立即继续到函数的下一行,并且fetch返回的promise将立即打印到控制台。
async function go() {
let response = fetch('http://www.example.com');
console.log(response); // print the promise from fetch immediately
}
go();
await
是一个上下文关键字,在标记为async
的函数中使用时仅表示特殊内容。通过标记函数async
,您告诉运行时:
yield
用户输入await
(通常是承诺)的值通过这种方式,可以以更接近传统同步样式的样式编写异步控制流。即。没有嵌套,回调或可见的承诺。 try..catch
也可以正常使用。
正如另一个答案所提到的,async
和await
是语法糖,要求运行时在后台使用现有对象(生成器函数和Promises),以使异步代码更易于读写。
你可以等待每一行吗?
我猜你可以。如果await
右侧的表达式产生了一个promise,那么就会出现上面详述的async / await行为。
如果await
右边的表达式没有产生一个promise,那么我猜这个值会包含在一个已经解决的promise中,并且逻辑会继续执行上面的操作,就像这个值来自一个立即解决的promise。这是猜测。
首先,async
/ await
,与承诺一起工作。如果你不是从async
函数调用或await
句子不是then
兼容,它将无法正常工作。在大多数情况下,如果你删除await
,你将以Promise
而不是承诺的价值结束。
其次,在某些情况下,您可能希望在解析某些异步任务时继续执行代码。