Jak mogę „spać” w programie Dart


110

Lubię symulować asynchroniczne wywołanie usługi internetowej w mojej aplikacji Dart do testowania. Aby zasymulować losowość tych próbnych wywołań odpowiadających (prawdopodobnie nie w kolejności), chciałbym zaprogramować moje makiety tak, aby czekały (spały) przez określony czas, zanim zwrócą „Przyszłość”.

Jak mogę to zrobić?

Odpowiedzi:


117

Możesz także użyć fabryki Future.delayed, aby zakończyć przyszłość po opóźnieniu. Oto przykład dwóch funkcji, które zwracają ciąg znaków asynchronicznie po opóźnieniu:

import 'dart:async';

Future sleep1() {
  return new Future.delayed(const Duration(seconds: 1), () => "1");
}

Future sleep2() {
  return new Future.delayed(const Duration(seconds: 2), () => "2");
}

9
Jaki jest cel () => "1"?
— Daksh Gargas

2
Chyba nie ma sensu, to tylko symbol zastępczy do wykonywania obliczeń
— Anil8753

1
Aby spać w aplikacji z tymi funkcjami, musisz użyć await:await sleep1();
— Slot

75

Edycja 2019:

W kodzie asynchronicznym

await Future.delayed(Duration(seconds: 1));

W kodzie synchronizacji

import 'dart:io';

sleep(Duration(seconds:1));

Uwaga: Spowoduje to zablokowanie całego procesu (izolację), więc inne funkcje asynchroniczne nie będą przetwarzane. Nie jest również dostępny w Internecie, ponieważ JavaScript jest tak naprawdę tylko asynchroniczny.


Jaka jest różnica między nimi dwoma (sleep vs Future.delayed)? Co dzieje się za kulisami w obu scenariuszach?
— Tomas Baran

3
sleep()całkowicie blokuje cały izolat. Żaden kod Dart w ogóle nie będzie działał podczas snu. Prawdopodobnie kompiluje się do czegoś podobnego do C ++ std::this_thread::sleep_for. Future.delayed()planuje późniejsze wznowienie funkcji asynchronicznej, ale następnie zwraca sterowanie do pętli zdarzeń Dart, aby inne funkcje asynchroniczne mogły nadal działać.
— Timmmm

68

Nie zawsze jest to to, czego chcesz (czasami chcesz Future.delayed), ale jeśli naprawdę chcesz spać w aplikacji wiersza poleceń Dart, możesz użyć dart: io's sleep():

import 'dart:io';

main() {
  sleep(const Duration(seconds:1));
}

Dobry! Niestety te informacje są trudne do znalezienia na oficjalnej stronie.
— Timur Fayzrakhmanov

12
Biblioteka „dart: io” nie jest dostępna, jeśli tworzysz aplikację internetową
— adeel41

5
From docs: używaj tego ostrożnie, ponieważ żadne operacje asynchroniczne nie mogą być przetwarzane w izolacji, gdy jest ono blokowane w wywołaniu [sleep].
— bartektartanus

2
UWAGA : To jest synchroniczne !!! Zatrzyma główny wątek! (Jestem takim głupcem, że zrobiłem await sleep()i spodziewam się innych zadań podczas snu :(
— ch271828n

1
Jaka jest różnica między nimi dwoma (sleep vs Future.delayed)? Co dzieje się za kulisami w obu scenariuszach?
— Tomas Baran

25

Odkryłem, że istnieje kilka implementacji w Dart, aby wykonać opóźnienie kodu:

new Future.delayed(const Duration(seconds: 1)); //recommend

new Timer(const Duration(seconds: 1), ()=>print("1 second later."));

sleep(const Duration(seconds: 1)); //import 'dart:io';

new Stream.periodic(const Duration(seconds: 1), (_) => print("1 second later.")).first.then((_)=>print("Also 1 second later."));
//new Stream.periodic(const Duration(seconds: 1)).first.then((_)=>print("Also 1 second later."));

17

Dla składni Dart 2+, w kontekście funkcji asynchronicznej:

import 'package:meta/meta.dart'; //for @required annotation

void main() async {
  void justWait({@required int numberOfSeconds}) async {
    await Future.delayed(Duration(seconds: numberOfSeconds));
  }

  await justWait(numberOfSeconds: 5);
} 

3

To przydatna makieta, która może przyjmować opcjonalny parametr, aby mockować błąd:

  Future _mockService([dynamic error]) {
    return new Future.delayed(const Duration(seconds: 2), () {
      if (error != null) {
        throw error;
      }
    });
  }

Możesz go używać w ten sposób:

  await _mockService(new Exception('network error'));

-2

Musiałem również poczekać na zakończenie usługi podczas testu jednostkowego. Zaimplementowałem w ten sposób:

void main()
{
    test('Send packages using isolate', () async {
        await SendingService().execute();
    });
    // Loop to the amount of time the service will take to complete
    for( int seconds = 0; seconds < 10; seconds++ ) {
        test('Waiting 1 second...', () {
            sleep(const Duration(seconds:1));
        } );
    }
}
...
class SendingService {
    Isolate _isolate;
    Future execute() async {
        ...
        final MyMessage msg = new MyMessage(...);
        ...
        Isolate.spawn(_send, msg)
            .then<Null>((Isolate isolate) => _isolate = isolate);
    }
    static void _send(MyMessage msg) {
        final IMyApi api = new IMyApi();
        api.send(msg.data)
            .then((ignored) {
                ...
            })
            .catchError((e) {
                ...
            } );
    }
}

To nie jest dobre, ponieważ zwykle nie wiesz, ile czasu zajmie ukończenie usługi.
— mcfly
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.