看看下面的Angular 1.x控制器:
class RootController
{
constructor($http)
{
this.variable = "apples";
// this.test($http); -- this works
// this.asyncTest($http); -- this doesn't
}
async asyncTest($http)
{
await $http.get('/api/someApiCall');
this.variable = "oranges";
// await $http.get('/api/someApiCall'); -- this makes this method work
}
test($http)
{
$http.get('/api/someApiCall').then(() => {
this.variable = "oranges";
});
}
}
如果我们取消注释构造函数中两行注释掉的行之一,则会得到不同的行为。如果我们运行test()
,则variable
将更新为值“ oranges”并按预期显示在视图中。如果我们运行asyncTest()
,则视图将继续显示“苹果”,直到某些东西强制摘要(出于某种原因,单击文本框和从文本框中退出似乎可以解决问题)。
另一个奇怪的问题是,如果我们取消注释await
中第二个asyncTest()
的注释,那么该方法现在可以正常工作了。
为什么会发生这种情况,为什么第二个await
会解决此问题?我认为await
几乎只是then
的语法糖,因此它们应该完全等效。我找到了一些有关此问题的文章,但它们更多地是关于解决问题的方法,而不是幕后的事情。
答案 0 :(得分:1)
据我了解,JavaScript中的Async Await功能是使用Promises和Generators的巧妙组合实现的,这对我来说太巧妙了,无法详细说明。但是如果您有兴趣,可以看看这些: https://chromium.googlesource.com/v8/v8.git/+/d08c0304c5779223d6c468373af4815ec3ccdb84/src/js/harmony-async-await.js#34
https://curiosity-driven.org/promises-and-generators
async/await native implementations
因此,由于Promise已解决且Angular脏检查/摘要循环将在生成器屈服之前完成,因此this.variable = "oranges";
函数中的asyncTest
将不会反映在UI中。
但是,当您在await $http.get('/api/someApiCall');
函数中添加注释行asyncTest
时,脏检查/摘要循环将再次被触发,从而更新UI。当您将重点放在文本框等字段之外时,也会发生同样的事情。
由于在test
函数内部,您正在this.variable = "oranges";
内部进行then
,所以一切正常。