看看下面的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(),那么变量将获得值“oranges”的更新并按预期显示在视图中.如果我们运行asyncTest(),视图将继续显示“apples”,直到某些内容强制摘要(出于某种原因,单击进出文本框似乎可以解决问题).
另一个奇怪的问题是,如果我们在asyncTest()中取消注释第二个await,那么该方法现在可以按预期工作.
为什么会发生这种情况,为什么第二个等待修复呢?我认为等待当时只是语法糖,所以这些应该是完全等价的.我找到了一些文章谈论这个问题,但他们更多的是关于如何解决它而不是在幕后发生的事情.
最佳答案 据我所知,Javascript中的Async Await功能是使用Promises和Generators的巧妙组合实现的,这对我来说太聪明了,无法详细解释.但如果您有兴趣,可以看一下这些:
https://curiosity-driven.org/promises-and-generators
async/await native implementations
因此,由于Promise已经解决并且Angular脏检查/摘要周期将在生成器产生之前完成,所以你的this.variable =“oranges”; asyncTest函数内部不会反映在UI中.
但是当你添加注释掉的行等待$http.get(‘/ api / someApiCall’);在asyncTest函数中,将再次触发脏检查/摘要周期,从而更新UI.当您从像文本框这样的某个字段聚焦时,会发生同样的事情.
因为在测试函数内部你正在做这个.变量=“橙子”;在那里,一切正常.