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.