为什么async / await破坏$ http.get /角度摘要周期?

时间:2018-08-30 07:42:34

标签: javascript angularjs async-await angular-promise

看看下面的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的语法糖,因此它们应该完全等效。我找到了一些有关此问题的文章,但它们更多地是关于解决问题的方法,而不是幕后的事情。

1 个答案:

答案 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,所以一切正常。

相关问题