Как узнать, когда мой код завершит всю асинхронную работу в зоне в Dart?

Считайте, что у меня есть такой код:

import 'dart:async';

foo() {
  print('foo');
}

bar() {
  print('bar');
}

void main() {
  runZoned(() {
    new Timer(const Duration(seconds: 1), foo);
    new Timer(const Duration(seconds: 2), bar);
  });
}

Как я могу узнать, когда вся асинхронная работа внутри зоны завершена? То есть можно ли узнать, когда все асинхронные методы (через таймер, будущее и т. д.), которые были зарегистрированы в зоне, завершены?


person Seth Ladd    schedule 26.02.2014    source источник


Ответы (2)


Изначально у зон был обратный вызов onDone. (См. использование в старом тесте здесь. ). Однако мы обнаружили, что слишком сложно отслеживать незавершенные обратные вызовы. Например: future.then(callback) регистрирует обратный вызов, но нет абсолютно никакой гарантии, что этот обратный вызов когда-либо будет вызван.

На самом деле, довольно часто фьючерсы никогда не завершаются. Зоны сами по себе вносят свой вклад в это: когда ошибка возникает в зоне, имеющей обработчик ошибок, ошибка никогда не покинет зону. Это означает, что future-цепочки за пределами зоны не будут завершены (ни со значением, ни с ошибкой, которую перехватила зона).

Вкратце: у нас было onDone в зонах, но мы удалили их, потому что это было непрактично.

person Florian Loitsch    schedule 26.02.2014
comment
Спасибо за фон. - person Seth Ladd; 27.02.2014
comment
onZoneLeave вызывается не только в конце, когда все обратные вызовы выполнены. Он вызывается после каждого run, который переключается в эту зону. Если вам это нужно в Dart, просто переопределите run в Dart`s Zones. - person Florian Loitsch; 02.03.2014

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

Возможно, можно создать производную зону, которая ведет учет запланированных задач (добавляет в свою очередь перед отправкой вызова в реализацию по умолчанию, а также упаковывает обратный вызов, чтобы получать уведомления при вызове обратного вызова, чтобы удалить его из очереди ).

Я надеюсь, что кто-то придумает лучший ответ.

person Günter Zöchbauer    schedule 26.02.2014
comment
Я думаю, что Angular делает что-то вроде производной зоны. См. github.com/angular/angular.dart/blob / - person Seth Ladd; 27.02.2014
comment
Я нашел github.com/angular/angular .dart/blob/master/lib/mock/. часто используется в модульных тестах, но, поскольку он находится в библиотеке mock, я подумал, что это просто издевательство. По вашей ссылке видно, что больше. Было бы здорово, если бы кто-нибудь из вас, знающие люди, написал статью о зонах. Кажется, что это играет важную роль в Dart, но его трудно понять и код трудно отлаживать. Я столкнулся со многими местами, где невозможно установить точки останова. С другой стороны, это кажется не слишком сложным, но слишком абстрактным, чтобы получить намерение из кода. - person Günter Zöchbauer; 27.02.2014
comment
Речь Брайана Форда посвящена зонам youtube.com/watch?v=3IqtmUscE_U. но речь идет о JS, а не о Dart. - person Günter Zöchbauer; 27.02.2014
comment
Я пытался понять, насколько речь Брайана имеет отношение к Дарту. Это действительно хорошо, и я в восторге от Zones. копия @florian-loitsch - person Seth Ladd; 28.02.2014