0

*解決済み問題は、firebase コールバックによって作成されたオブザーバブルを作成して応答する方法にありました。また、firebase コールバック内であまりにも多くのことが行われていました。firebase promise 構造を使用して、もう少し分割することになりまし た現在 firebaseAPI.checkForUser と呼ばれるもの内のコールバック。*

作業叙事詩:

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

// 元の質問

わかりましたので、私が達成しようとしているのは、最初のアクション (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,
    });
  }
};
4

1 に答える 1

2

問題は、mergeサブスクライブするストリームの順序を維持しないことです。ソース ストリームが発行する順序に関係なく、任意のソース ストリームからイベントを発行するだけです。

順序を維持する必要がある場合は、concat代わりに使用する必要がありますmerge

すなわち

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

補足として、なぜそこで演算子を使用しているのかわかりません。すでに API から Observables が返されているため、この場合はorにof渡すことができます。mergeconcat

于 2016-12-22T06:05:09.907 に答える