39

redux-saga プロジェクトはかなり前から存在していますが、このライブラリについてはまだ多くの混乱を招くことがあります。それらの 1 つは、rootSaga を開始する方法です。たとえば、初心者のチュートリアルでは、rootSaga はサガの配列を生成することによって開始されます。このような

export default function* rootSaga() {
  yield [
    helloSaga(),
    watchIncrementAsync()
  ]
}

ただし、saga ヘルパーの使用セクションでは、rootSaga は 2 つのフォークされた saga で構成されています。このような:

export default function* rootSaga() {
  yield fork(watchFetchUsers)
  yield fork(watchCreateUser)
}

rootSaga を開始するのと同じ方法が、redux-saga リポジトリの非同期の例で使用されています。ただし、現実世界とショッピング カードの例を確認すると、そこにある rootSagas がフォークされたサガの配列を生成することがわかります。このような:

export default function* root() {
  yield [
    fork(getAllProducts),
    fork(watchGetProducts),
    fork(watchCheckout)
  ]
}

また、redux-saga の問題に関するいくつかの議論を読むと、フォークされたサガの 1 つが未処理の例外のためにキャンセルされた場合にアプリケーションが完全にクラッシュするのを防ぐために、rootSaga に fork の代わりに spawn を使用することを提案する人がいることがわかります。

では、rootSaga を開始する最も正しい方法はどれですか? そして、既存のものとの違いは何ですか?

4

2 に答える 2

16

rootSaga の作成方法

redux-saga [ 1、2]のコア開発者によると、rootSaga を作成する慣用的な方法は、all Effect Combinatorを使用することです。また、saga から配列を生成することは推奨されないことに注意してください。

例 1

このようなものを使用できます(+all)

import { fork, all } from 'redux-saga/effects';
import firstSaga from './firstSaga';
import secondSaga from './secondSaga';
import thirdSaga from './thirdSaga';

export default function* rootSaga() {
    yield all([
        fork(firstSaga),
        fork(secondSaga),
        fork(thirdSaga),
    ]);
}

例 2

ここから撮影

// foo.js
import { takeEvery } from 'redux-saga/effects';
export const fooSagas = [
  takeEvery("FOO_A", fooASaga),
  takeEvery("FOO_B", fooBSaga),
]

// bar.js
import { takeEvery } from 'redux-saga/effects';
export const barSagas = [
  takeEvery("BAR_A", barASaga),
  takeEvery("BAR_B", barBSaga),
];

// index.js
import { fooSagas } from './foo';
import { barSagas } from './bar';

export default function* rootSaga() {
  yield all([
    ...fooSagas,
    ...barSagas
  ])
}

フォークとスポーン

forkspawnはどちらもTaskオブジェクトを返します。フォークされたタスクは親にアタッチされますが、スポーンされたタスクは親から切り離されます。

  • フォークでのエラー処理 [リンク]:

    子タスクからのエラーは、自動的にその親にバブル アップします。フォークされたタスクでキャッチされていないエラーが発生した場合、親タスクは 子 Errorで中止され、親の実行ツリー全体 (つまり、フォークされたタスク + まだ実行中の場合は親の本体で表されるメイン タスク)がキャンセルされます。

  • 生成されたタスクでのエラー処理 [リンク]:

    親は、切り離されたタスクが終了するのを待ってから戻ることはなく、親または切り離されたタスクに影響を与える可能性のあるすべてのイベントは完全に独立しています(エラー、キャンセル)。

上記に基づいて、「ミッション クリティカルな」タスク、つまり「このタスクが失敗した場合はアプリ全体をクラッシュさせてください」に fork を使用し、「このタスクが失敗した場合、アプリ全体をクラッシュさせてください」、「重要ではない」タスクに spawn を使用できます。親へのエラー」。

于 2017-12-03T20:47:08.837 に答える