Comment puis-je «mettre en veille» un programme Dart

102

J'aime simuler un appel de service Web asynchrone dans mon application Dart à des fins de test. Pour simuler le caractère aléatoire de la réponse de ces faux appels (peut-être dans le désordre), j'aimerais programmer mes simulacres pour attendre (dormir) pendant un certain temps avant de renvoyer le «futur».

Comment puis-je faire ceci?

Vinnie
la source

Réponses:

111

Vous pouvez également utiliser l'usine Future.delayed pour terminer un futur après un délai. Voici un exemple de deux fonctions qui retournent une chaîne de manière asynchrone après un délai:

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");
}
Shailen Tuli
la source
8
Quel est le but de () => "1"?
Daksh Gargas
2
Je suppose que cela ne sert à rien, c'est juste un espace réservé pour faire vos calculs
Anil8753
66

Ce n'est pas toujours ce que vous voulez (parfois vous voulez Future.delayed), mais si vous voulez vraiment dormir dans votre application de ligne de commande Dart, vous pouvez utiliser dart: io's sleep():

import 'dart:io';

main() {
  sleep(const Duration(seconds:1));
}
Seth Ladd
la source
Bien! Malheureusement, cette information est difficile à trouver sur le site officiel.
Timur Fayzrakhmanov
11
La bibliothèque 'dart: io' n'est pas disponible si vous
créez
4
À partir de la documentation: utilisez ceci avec précaution, car aucune opération asynchrone ne peut être traitée dans un isolat alors qu'il est bloqué dans un appel [sleep].
bartektartanus
1
AVERTISSEMENT : C'est synchrone !!! Cela arrêtera le fil principal! (Je suis un imbécile de ce que j'ai fait await sleep()et je m'attends à ce que les autres travaux s'exécutent pendant le sommeil :(
ch271828n
1
Quelle est la différence entre les deux (Sleep vs Future.delayed)? Que se passe-t-il dans les coulisses des deux scénarios?
Tomas Baran le
62

Édition 2019:

Dans le code asynchrone

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

Code de synchronisation

import 'dart:io';

sleep(Duration(seconds:1));

Remarque: Cela bloque l'ensemble du processus (isoler), de sorte que les autres fonctions asynchrones ne seront pas traitées. Il n'est pas non plus disponible sur le Web car Javascript est vraiment uniquement asynchrone.

Timmmm
la source
Quelle est la différence entre les deux (Sleep vs Future.delayed)? Que se passe-t-il dans les coulisses des deux scénarios?
Tomas Baran le
3
sleep()bloque complètement l'isolat entier. Aucun code Dart ne s'exécutera pendant qu'il est en veille. Il compile probablement à quelque chose comme C ++ std::this_thread::sleep_for. Future.delayed()planifie la reprise ultérieure de la fonction asynchrone, mais elle retourne ensuite le contrôle de la boucle d'événements Dart afin que d'autres fonctions async puissent continuer à s'exécuter.
Timmmm
24

J'ai trouvé qu'il existe plusieurs implémentations dans Dart pour retarder l'exécution du code:

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."));
SpkingR
la source
16

Pour la syntaxe Dart 2+, dans un contexte de fonction asynchrone:

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);
} 
Bono Niv
la source
3

C'est une simulation utile qui peut prendre un paramètre facultatif pour simuler une erreur:

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

Vous pouvez l'utiliser comme ceci:

  await _mockService(new Exception('network error'));
Jannie Theunissen
la source
-2

J'avais également besoin d'attendre la fin d'un service lors d'un test unitaire. J'ai implémenté de cette façon:

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) {
                ...
            } );
    }
}
Luciano
la source
Ce n'est pas bon car vous ne savez généralement pas combien de temps votre service prend pour terminer.
mcfly