2
votes

Flutter StreamSubscription ne s'arrête pas ou ne s'arrête pas

Dans mon application Flutter, StreamSubscription ne met pas en pause ou ne s'annule pas. Lorsque j'appelle cancel () s'il a déjà commencé, il s'arrêtera. Si j'appelle cancel () après le démarrage, cela ne s'arrêtera pas. J'utilise l'écouteur de snapshot Firestore. Ci-dessous mon code. J'ai essayé différentes méthodes mais cela ne fonctionne toujours pas. Le problème est que le listener de Firestore ne s’arrête pas après le chargement des données.

    StreamSubscription<QuerySnapshot> streamSubscription;

    @override
    void initState() {
    super.initState();
    
        print("Creating a streamSubscription...");
        streamSubscription =Firestore.collection("name").document("d1").collection("d1")
            .snapshots().listen((data){
                //It will display items
            }, onDone: () { // Not excecuting
                print("Task Done");
            }, onError: (error) {
                print("Some Error");
        });
         streamSubscription.cancel(); //It will work but cancel stream before loading
    }

    @override
    void dispose() {
     streamSubscription.cancel(); //Not working
    super.dispose();
    }


7 commentaires

stream.close () doit être stream.cancel () et un StreamSubscription doit plutôt être appelé streamSubscription ou < code> abonnement au lieu de stream car c'est assez déroutant car un Stream est tout autre chose.


Il n'y a pas de close () dans api.dartlang.org/stable/2.2.0/dart-async/... il n'est donc pas surprenant que cela ne fonctionne pas. Si vous recevez un message d'erreur, vous devez publier ce message avec votre question.


J'ai édité ma question. J'utilise 'cancel ()' not close. Désolé pour une erreur.


@ GünterZöchbauer saviez-vous pourquoi cela ne s'arrête pas?


Dur à dire. Peut-être parce que les événements sont émis synchronisés et donc émis avant que cancel () ne soit appelé. Votre question n'est pas assez claire sur ce qui se passe réellement et quel est le comportement attendu. Si vous pouviez améliorer cela, la probabilité que vous obteniez une réponse utile augmenterait.


@ GünterZöchbauer quand je vais sur une autre page, l'auditeur ne s'arrête pas. Il exécute une nouvelle page et interrompt un autre écouteur. J'ai ajouté annuler dans dispose (), il n'annule pas et n'exécute pas une nouvelle page.


continuons cette discussion dans le chat


3 Réponses :


3
votes

Lorsque vous envoyez une nouvelle page, la page précédente est toujours rendue et par conséquent dispose () n'est pas appelée.

Parfois aussi, il peut arriver que le widget ne soit plus rendu mais que dispose n'a pas encore été appelé, ce qui peut conduire à des messages d'erreur étranges. Donc, ajouter une telle vérification est probablement aussi une bonne idée si vous utilisez dispose .

Change

if(myIsCurrentRoute && mounted) {
  //It will display items
}

to

//It will display items


0 commentaires

1
votes

Vous n'attribuez pas l'abonnement à la bonne variable.

StreamSubscription<QuerySnapshot> subscription;

@override
void initState() {
super.initState();

    print("Creating a streamSubscription...");
    subscription=Firestore.collection("name").document("d1").collection("d1")
        .snapshots().listen((data){
            //It will display items
        }, onDone: () { // Not excecuting
            print("Task Done");
        }, onError: (error) {
            print("Some Error");
    });


     subscription.cancel(); //It will work but cancel stream before loading



}

@override
void dispose() {
 subscription.cancel(); //Not working
super.dispose();
}


4 commentaires

Telle est l'erreur dans ma question. Je change ma question. J'ai assigné. Corriger l'abonnement dans la variable de droite. Veuillez à nouveau vérifier la question et vérifier votre réponse.


@Joe Avez-vous essayé si la fonction dispose est appelée du tout? Essayez d'imprimer quelque chose dans la fonction de mise au rebut et voyez si elle est appelée.


J'ai essayé dans dispose () mon dispose () fonctionne mais n'annule pas l'écoute. J'ai également appelé avant d'appeler un nouvel écran. Navigator.push (contexte, MaterialPageRoute (constructeur: (context) => SecondScreen ()));


Quelqu'un peut-il me dire pourquoi onDone ne s'exécute pas ici?



1
votes

J'avais le même problème et il s'avère que le flux semble continuer à écouter les événements pendant un certain temps avant de s'annuler, mais si vous déboguez, vous verrez qu'après l'appel de dispose, il cessera d'écouter à un moment donné. Par conséquent, la solution Gunter fonctionne correctement, car vous pouvez empêcher votre fonction de rappel d'être appelée si mount est faux, ce qui signifie que votre page n'est plus là.


0 commentaires