J'aime simuler un appel de service Web asynchrone dans mon application Dart pour le tester. Pour simuler le caractère aléatoire de ces appels simulés répondant (éventuellement en panne), j'aimerais programmer mes simulations pour attendre (dormir) pendant un certain temps avant de renvoyer le "Futur".
Comment puis-je faire ceci?
Vous pouvez également utiliser la fabrique Future.delayed pour terminer un avenir après un délai. Voici un exemple de deux fonctions qui renvoient 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");
}
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: sleep()
:
import 'Dart:io';
main() {
sleep(const Duration(seconds:1));
}
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);
}
J'ai trouvé qu'il y avait plusieurs implémentations dans Dart pour que le code soit retardé:
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."));
C'est une maquette 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'));
J'avais également besoin d'attendre qu'un service soit terminé lors d'un test unitaire. J'ai implémenté cette manière:
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) {
...
} );
}
}