0

* SOLVED Firebaseコールバックによって作成されたオブザーバブルを作成して応答する方法が問題でした。 ファイヤーベースのコールバックの中で、あまりにも多くのことが起こっていました。 firebase約束の構造を使用してもう少し分けて分割しました:https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html firebaseAPI.checkForUserと呼ばれるFirebaseコールバックのObservable.fromPromiseを作成します。 *叙事詩の関数が順不同で発砲している理由を理解できません

の作業叙事詩:

export const contactFormFirebaseSubmitEpic = (action$) => 
action$.ofType(START_CONTACT_FORM_FIREBASE_SUBMIT) 
    .flatMap((firebaseSubmitAction) => { 
    const values = firebaseSubmitAction.values; 
    const formattedEmail = firebaseAPI.getFormattedEmail(values); 
    const contactsRef = firebaseAPI.getContactsRef(formattedEmail); 
    return firebaseAPI.checkForUser(values, formattedEmail, contactsRef); 
}) 
    .flatMap((data) => concat(
     of(firebaseAPI.recordUserAndUpdateDetails(data)) 
    )) 
    .flatMap((data) => concat(
    of(firebaseAPI.setQuoteData(data)) 
    )) 
    .switchMap((x) => merge(
     of(stopLoading()), 
     of(contactFormFirebaseSuccess()) 
    )); 

//元の質問

[OK]をので、私は(firebaseAPI.checkUserAndUpdateを)最初のアクションを実行するために達成するためにされてしようとしているものを、次の、両方が実行されると、本質的にそこにあるものは破棄され、2つのアクション(contactFormFirebaseSuccessおよびstopLoading)が送出されます。

これはすべて奇妙なこと以外はうまくいきますが、setQuoteData関数は常にcheckUser関数の前に実行されます。なぜ誰がこのことが分かっているのですか?

また、これをレイアウトするためのより良い方法がある場合は、私は非常に参考にしています。乾杯。また、私はかなり複雑なものになるかなりの変数と事柄を取り出しました。基本的には、私はそれぞれのケースで、「firebaseで何かをやって」から観測を返すことを示したかっただけです。しかし、firebase関数のそれぞれにコンソールログがあり、setQuoteDataが最初に起動した後、firebaseのものを実行してから、checkUserAndUpdateが実行されたときにコンソールログが問題になるとは思わない。

export const contactFormFirebaseSubmitEpic = action$ => 
action$.ofType(START_CONTACT_FORM_FIREBASE_SUBMIT) 
.flatMap((firebaseSubmitAction) => { 
    const values = firebaseSubmitAction.values; 
    return merge(
    firebaseAPI.checkUserAndUpdate(values), 
    firebaseAPI.setQuoteData(values), 
) 
    .takeLast(1) 
    .mergeMap((x) => { 
    return merge(
     of(contactFormFirebaseSuccess()), 
     of(stopLoading()), 
    ); 
    }); 
}); 


const firebaseAPI = { 

    checkUserAndUpdate: (values) => { 
    const checkUserAndUpdateDetails = firebaseRef.once('value', snapshot => { 
    const databaseValue = snapshot.val(); 
    checkUserExistsAndUpdateDetails(databaseValue, values); 
    }); 
    return Observable.from(checkUserAndUpdateDetails); 
    }, 

    setQuoteData: (value) => { 
    const setQuote = setQuoteData(values); 
    return Observable.from(setQuote); 
    }, 
}; 

const stopLoading =() => ({ type: STOP_BUTTON_LOADING }); 
const contactFormFirebaseSuccess =() => ({ type: SUCCESS }); 

checkUserAndUpdate: (values, contactsRef) => { 
    const checkUser$ = Observable.from(contactsRef.once('value').then( 
    snapshot => { 
    const databaseValue = snapshot.val(); 
    checkUserExistsAndUpdateDetails(
     values, 
     databaseValue, 
     contactsRef,); 
    }) 
); 
    return checkUser$; 
}, 

const checkUserExistsAndUpdateDetails = (
    values, 
    databaseValue, 
    contactsRef, 
) => { 
if (databaseValue) { console.log('user exists'); } 
    else { 
    console.log('new user, writing to database'); 
    contactsRef.set({ 
     name: values.name, 
     email: values.email, 
     phone: values.phone, 
    }); 
    } 
}; 
+0

checkUserAndUpdateDetailsは同期型ではなく(コールバックを使用します)、setQuoteData *は同期型です。それはそれが最初に値を送信します、それは完了するためにコールバックを必要としません – aarosil

+0

こんにちは、しかし、完全な関数は含まれていませんでしたが、setQuoteDataは非同期ですか?しかし、私はそれが潜在的に最も速く完了すると言うでしょう、それは重要ですか?私は最後に完了するまでに始めるべきではないと思った? –

+0

しかし、checkUser ...関数がfirebase経由でコールバックに明示的に入っているという点が分かります...私がflatMap(最初の関数を実行する)のようなものを実行しているのは、それらを実行する.flatMap(2番目の関数を実行する)です。正しい順序ですが、そのインスタンスの2番目の関数にどのようにソース値を渡すのでしょうか?つまり、最初のflatMapから返される値はありませんか? –

答えて

2

問題はmergeは、あなたが購読ストリームの順序を維持しないということです、それは単にソースのいずれかからイベントを発するかかわらず、彼らが発するどのような順序のストリーム。

あなたが

const values = firebaseSubmitAction.values; 
    return concat(
    firebaseAPI.checkUserAndUpdate(values), 
    firebaseAPI.setQuoteData(values), 
) 

サイドノート、つまり代わりにmerge

concatを使うべき秩序を維持する必要がある場合がありof演算子を使用している理由は、私は知らない、あなたはすでに観測を持っていますあなたのAPIから返されるので、この場合はmergeまたはconcatに渡すことができます。

+0

大きな意味があります。私はそれを試して喜びを与えるよ! –

+0

完璧に感謝しました! –

+0

実際には、ユーザーが存在せず、firebaseコールバックに入る必要がある場合でも、それは間違った順序になります。また、mergeMapをconcatMapに変更しただけでなく、concatMap内で連結するようにマージしました。 –

関連する問題