2017-01-23 4 views
1

Observablesをゆっくりと取得していますが、Firebaseは結果を得るために多くのクレイジーなものを必要としているようです。 P基本的には、私はFirebaseデータベースから取得するユーザの配列を作成するために、いくつかの条件に基づいていくつかのキーをフィルタリングする機能を持っています。角2 Observables - Observableを実行する前に操作が完了するまで待つ必要があります

しかし、フィルタリング機能が終了する前にObservableが実行されているため、競合状態に陥っています。 My機能は(少なくとも私には)少し複雑ですので、私は、私はObservable.combineLatestコールを開始する前に、userKeysが最新であることを確認するために何ができるかを正確にはわからない:

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; 
     }) 
     }); 
    }); 
    } 

誰もがいずれかを持っていますアイデア?

答えて

0

私はObservableのすべてのロジックを試してみてください。試してみて、観測可能なものを退会しなければならないことを覚えておいてください!

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

回答ありがとうございます。私は実際にこれを数日間苦労してきました。ここではたくさんのことが起こっているようですが、私はそれを試してみたところで、私が期待していることをしているようには思えません:/例えば、会話を削除しても、そこに消えていくのではなく、私はまた、他の奇妙な予期しないことが起きている。しかし、うーん、これはこれらすべての呼び出しをObservableの1つに統合する最善の方法だと思いますか? –

関連する問題