【问题标题】:Why does async/await break $http.get/the angular digest cycle?为什么 async/await 会打破 $http.get/角度摘要循环?
【发布时间】:2019-02-05 01:59:10
【问题描述】:

看看下面的 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(),视图会继续显示“苹果”,直到某些东西强制执行摘要(出于某种原因,点击进出文本框似乎可以解决问题)。

另一个奇怪的问题是,如果我们取消注释 asyncTest() 中的第二个 await,那么该方法现在可以按预期工作。

为什么会发生这种情况,为什么第二个await 会修复它?我认为await 几乎只是then 的语法糖,所以它们应该是完全等价的。我发现一些文章讨论了这个问题,但它们更多地是关于如何解决这个问题,而不是幕后发生的事情。

【问题讨论】:

  • 你是在使用 Babel 来改造 Async Await 吗?如果是这样,您使用的是什么插件或转换?
  • @ajaybc 不,这都是纯 JavaScript。我写的是浏览器运行的。
  • $http 返回一个 Observable,async / await 用于 Promises。试试await $http.get('').toPromise()
  • @Baruch 在angularjs 它返回一个HttpPromise...
  • @Baruch,不幸的是,您假设错误

标签: javascript angularjs async-await angular-promise


【解决方案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 脏检查/摘要循环将在生成器产生之前完成,因此 asyncTest 函数中的 this.variable = "oranges"; 不会反映在 UI 中。 但是当您在asyncTest 函数中添加注释掉的行await $http.get('/api/someApiCall'); 时,脏检查/摘要循环将再次触发,从而更新UI。当您将注意力集中在文本框等字段之外时,也会发生同样的事情。

由于在test 函数内部你在then 内部执行this.variable = "oranges";,所以一切正常。

【讨论】:

    猜你喜欢
    • 2016-10-31
    • 1970-01-01
    • 2017-10-26
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    • 1970-01-01
    相关资源
    最近更新 更多