Почему async / await прерывает $ http.get / цикл углового дайджеста? - PullRequest
0 голосов
/ 30 августа 2018

Посмотрите на следующий контроллер 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 получит обновления значения «апельсины» и отобразит в представлении, как и ожидалось. Если мы запустим asyncTest(), представление продолжит отображать «яблоки», пока что-то не вызовет дайджест (по какой-то причине щелчок в и из текстового поля, кажется, делает свое дело).

Еще одна странная проблема заключается в том, что если мы раскомментируем второй await в asyncTest(), то этот метод теперь работает, как и ожидалось.

Почему это происходит, и почему второй await исправляет это? Я думал, что await был просто синтаксическим сахаром для then, поэтому они должны быть полностью эквивалентны. Я нашел несколько статей, рассказывающих об этой проблеме, но они больше о том, как ее исправить, чем о том, что происходит под капотом.

1 Ответ

0 голосов
/ 30 августа 2018

Насколько я понимаю, функциональность Async Await в Javascript реализована с использованием умной комбинации Promises и Generators, которая слишком умен, чтобы я мог объяснить подробно. Но вы можете взглянуть на это, если вам интересно: https://chromium.googlesource.com/v8/v8.git/+/d08c0304c5779223d6c468373af4815ec3ccdb84/src/js/harmony-async-await.js#34

https://curiosity -driven.org / Обещания-и-генераторы

Асинхронное / ожидание собственных реализаций

Таким образом, поскольку Обещание разрешено, и цикл проверки / дайджеста Угловой грязи будет завершен до того, как генератор сработает, ваш this.variable = "oranges"; внутри функции asyncTest не будет отражен в пользовательском интерфейсе. Но когда вы добавляете закомментированную строку await $http.get('/api/someApiCall'); в функцию asyncTest, цикл грязной проверки / дайджеста будет снова запущен, тем самым обновляя пользовательский интерфейс. То же самое происходит, когда вы фокусируете внимание на каком-либо поле, таком как текстовые поля.

Поскольку внутри функции test вы выполняете this.variable = "oranges"; внутри then, все работает нормально.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...