web-dev-qa-db-fra.com

Appel d'une méthode asynchrone à partir du constructeur de composants dans Dart

Supposons qu'une initialisation de MyComponent dans Dart nécessite l'envoi d'une requête HttpRequest au serveur. Est-il possible de construire un objet de manière synchrone et de différer une "vraie" initialisation jusqu'à ce que la réponse revienne?

Dans l'exemple ci-dessous, la fonction _init () n'est pas appelée tant que "done" n'est pas imprimé. Est-il possible de réparer ça?

import 'Dart:async';
import 'Dart:io';

class MyComponent{
  MyComponent() {
    _init();
  }

  Future _init() async {
    print("init");
  }
}

void main() {
  var c = new MyComponent();
  sleep(const Duration(seconds: 1));
  print("done");
}

Sortie:

done
init
30
typedef

Un constructeur ne peut renvoyer qu'une instance de la classe dont il est constructeur (MyComponent). Votre exigence obligerait un constructeur à renvoyer Future<MyComponent> qui n'est pas pris en charge.

Vous devez soit créer une méthode d'initialisation explicite qui doit être appelée par l'utilisateur de votre classe comme:

class MyComponent{
  MyComponent();

  Future init() async {
    print("init");
  }
}

void main() async {
  var c = new MyComponent();
  await c.init();
  print("done");
}

ou vous démarrez l'initialisation dans le consturctor et permettez à l'utilisateur du composant d'attendre que l'initialisation soit effectuée.

class MyComponent{
  Future _doneFuture;

  MyComponent() {
    _doneFuture = _init();
  }

  Future _init() async {
    print("init");
  }

  Future get initializationDone => _doneFuture
}

void main() async {
  var c = new MyComponent();
  await c.initializationDone;
  print("done");
}

Quand _doneFuture était déjà terminé await c.initializationDone revient immédiatement sinon il attend que le futur se termine en premier.

19
Günter Zöchbauer

Vous pouvez utiliser _init () comme méthode static. Cela pourrait être une solution plus soignée à votre problème:

import 'Dart:async';
import 'Dart:io';

class MyComponent{
  MyComponent();
  static Future init() async {
    print("init");
  }
}

void main() async {
  var c = await MyComponent.init();
  sleep(const Duration(seconds: 1));
  print("done");
}

N'oubliez pas de marquer la fonction dans laquelle vous utilisez votre init () dans async.

0
Syed Mushaheed