1

Apollo-Client を使用して、GraphQL サーバーへのクエリとミューテーションを作成しています。Apollo には独自のエラー処理があるため、takeUntil 関数を実装してクエリ呼び出しとミューテーションをキャンセルするのは非常に困難です。

Apollo を使用すると、私のミューテーションは次のようになります。

export const languageTimeZoneEpic = (action$) => {
  return action$.ofType(CHANGE_LANGUAGE)
    .mergeMap(action => client.mutate({
      mutation: languageMutation,
      variables: { id: action.id,  language: action.selected_language }
    }).then(result => changeLanguageFulfilled(result))
      .catch(error => changeLanguageError(error))
  );
};

私のミューテーションは問題なく作成され、エラーがあればそれをキャッチします。ここでの問題は、takeUntil()以下の例のように関数を追加すると、関数がまったく機能しなくなることです。

export const languageTimeZoneEpic = (action$) => {
  return action$.ofType(CHANGE_LANGUAGE)
    .mergeMap(action => client.mutate({
      mutation: languageMutation,
      variables: { id: action.id,  language: action.selected_language }
    }).then(result => changeLanguageFulfilled(result))
      .catch(error => changeLanguageError(error))
  ).takeUntil("END_LANGUAGE");
};

takeUntil()独自のエラーハンドリングを持つクライアントを使用していても 、関数を使用できる方法がないか疑問に思っていました。

* ここでの takeUntil() は、ミューテーションが完了する前に別のアクションをディスパッチすると呼び出されます。

ありがとうございました

4

1 に答える 1

1

takeUntil引数として文字列を受け入れません。代わりに、最初の next'd 値をシグナルとして使用して、サブスクライブする Observable を期待します。

redux-observable は 99.9% だけの RxJS であるため、 redux-observable が提供する唯一のオペレーターを除いて、すべてのオペレーターは redux/action について何も知りませんofType。残りは RxJS 組み込みです。

孤立の問題もあります。takeUntilを の外側に配置するmergeMapと、特定の apollo-client クライアントだけでなく、Epic 全体がキャンセルされます。代わりに、に配置する必要mergeMapがあり、Promise を扱っているため、Observable.fromそれをラップするために使用する必要があります。

export const languageTimeZoneEpic = (action$) => {
  return action$.ofType(CHANGE_LANGUAGE)
    .mergeMap(action =>
      Observable.from(
        client.mutate({
          mutation: languageMutation,
          variables: { id: action.id,  language: action.selected_language }
        })
        .then(result => changeLanguageFulfilled(result))
        .catch(error => changeLanguageError(error))
      )
        .takeUntil(action$.ofType('END_LANGUAGE'))
    );
};

ただし、Promise を使用して、thenこのcatchように間違いなく場違いです。Promise を使用することを好む場合は、redux-observable を使用しないことをお勧めします。redux-observable を使用する場合、通常、他に選択肢がない場合 (たとえば、apollo-client API を制御しない場合) にのみ Promises を使用します。これらの場合、私は通常、Observable としてできるだけ早くそれらをラップし、残りは通常の RxJS です。

export const languageTimeZoneEpic = (action$) => {
  return action$.ofType(CHANGE_LANGUAGE)
    .mergeMap(action =>
      Observable.from(client.mutate({
        mutation: languageMutation,
        variables: { id: action.id,  language: action.selected_language }
      }))
        .map(result => changeLanguageFulfilled(result))
        .catch(error => Observable.of(
          changeLanguageError(error)
        ))
        .takeUntil(action$.ofType('END_LANGUAGE'))
    );
};

これは、より冗長であることを意味する場合もありますが、ほとんどの場合、Promise を使用しないことに関するものcatchです。「これはPromiseキャッチですか、それともObservableキャッチですか?」. もちろん、これは私の意見です:)


実際の Promise はキャンセルできないため、apollo-client がミューテーションを実際にキャンセルする方法はないと仮定しました。このコードは、Promise の結果を真にキャンセルするのではなく、技術的に無視します (不可能です)。

于 2017-07-17T18:29:42.197 に答える