2017-01-23 2 views
1

Ich habe langsam den Dreh der Observablen erreicht, obwohl Firebase von Ihnen verlangt, eine Menge verrückter Sachen mit ihnen zu machen, um erzielte Ergebnisse zu erzielen: P Im Grunde genommen habe ich eine Funktion, mit der ich einige Schlüssel basierend auf bestimmten Bedingungen ausfiltern kann, um ein Array von Benutzern zu erstellen, die aus meiner Firebase-Datenbank greifen können.Angular 2 Observables - Müssen warten, bis Operationen ausgeführt werden, bevor sie Observable ausgeführt werden

Allerdings ist das Observable ausgeführt, bevor meine Filterfunktion beenden kann, so dass ich in eine Race-Bedingung renne. Meine Funktion ist ein wenig komplex (zumindest für mich), also bin ich nicht ganz sicher, was ich tun kann, die userKeys sind auf dem neuesten Stand zu gewährleisten, bevor die Observable.combineLatest callte wird:

getUsersForConversations(conversations) { 
    conversations.forEach((conversation, index) => { 

     // Get user out of local storage 
     this.storage.get('user').then(user => { 

     // Iterate through the users and remove the current user 
     // to prevent an unecessary call being made 
     let userKeys = Object.keys(conversation.users); 

     userKeys.forEach((key, index) => { 
      if(key === user.id) { 
      userKeys.splice(index, 1); 
      } else { 

      if(userKeys.length > 0) { 

       // Grab the conversation for this user and determine 
       // If the conversation has been removed before 
       this._af.database 
       .object(`/social/conversations_last_deleted/${conversation.$key}/${user.id}`) 
       .subscribe(lastDeleted => { 

       if(lastDeleted && (lastDeleted.$value !== null)) { 
        this._messages.getMessagesForConvo(conversation.$key, lastDeleted).subscribe(messages => { 

        if(messages.length === 0) { 
         userKeys.splice(index, 1); // This is updated after the Observable.combineLatest :(
        } 
        }) 
       }; 
       }); 
      } 
      } 
     }); 

     // Get all the users based on this list and shove them 
     // into the correct conversation 

     Observable.combineLatest(
      userKeys.map((userKey) => this._af.database 
      .object(`/social/users/${userKey}`) 
     ) 
     ).subscribe(users => { 
      conversations[index].users = users; 
      this.conversations = conversations; 
     }) 
     }); 
    }); 
    } 

Hat jemand irgendwelche Ideen?

Antwort

0

Nun, ich versuche, alle Logik in einem Observable zu tun, bitte versuchen Sie es und erinnern Sie sich, dass Sie die Observables abbestellen müssen !!

getUsersForConversations(conversations) { 
    conversations.forEach((conversation, index) => { 

     // Get user out of local storage 
     this.storage.get('user').then(user => { 

     let userKeys = Object.keys(conversation.users); 

     let sub = Observable 
      .from(userKeys) 
      .filter(key => (key != user.id && key.length > 0)) 
      .flatMap(key => 
      Observable.zip(
       Observable.of(key), 
       this._af.database.object(`/social/conversations_last_deleted/${conversation.$key}/${user.id}`) 
       .filter(lastDeleted => (lastDeleted && (lastDeleted.$value !== null))) 
       .flatMap(lastDeleted => this._messages.getMessagesForConvo(conversation.$key, lastDeleted)), 
       (key, messages) => { 
       if (messages.length === 0) { 
        return null; 
       } 
       return key; 
       }) 
     ) 
      .filter(key => key != null) 
      .flatMap(userKey => this._af.database.object(`/social/users/${userKey}`)) 
      .subscribe(users => { 
      conversations[index].users = users; 
      this.conversations = conversations; 
      }); 

      // REMEMBER TO ALWAYS UNSUBSCRIBE!!!! or you will have memory leaks.... 
      sub.unsubscribe(); 

     }); 
    }); 
    } 
+0

Danke für die Antwort Victor. Ich kämpfe seit Tagen damit. Es scheint hier eine Menge los zu sein, und da ich daran herumgebastelt habe, scheint es nicht ganz so zu sein, wie ich es erwarte:/Wenn ich zum Beispiel eine Konversation entferne, bleibt das Listenelement immer noch dort, anstatt zu verschwinden. Ich bekomme auch andere seltsame und unerwartete Dinge passieren. Aber hmm, das ist also der beste Weg, all diese Anrufe in ein Observable zu integrieren, denkst du? –

Verwandte Themen