APIリファレンス
ミドルウェア API
createSagaMiddleware(options)
Reduxミドルウェアを作成し、SagaをRedux Storeに接続します。
options: Object
- ミドルウェアに渡すオプションのリスト。現在サポートされているオプションは次のとおりです。context: Object
- Sagaのコンテキストの初期値。sagaMonitor
: SagaMonitor - Saga Monitorが提供されている場合、ミドルウェアは監視イベントをモニターに配信します。onError: (error: Error, { sagaStack: string })
- 提供されている場合、ミドルウェアはSagaからのキャッチされないエラーでそれを呼び出します。キャッチされない例外をエラー追跡サービスに送信するのに役立ちます。effectMiddlewares
: Function [] - すべてのエフェクトをインターセプトし、独自に解決して次のミドルウェアに渡すことができます。詳細な例については、このセクションを参照してくださいchannel
: 提供されている場合、ミドルウェアは、デフォルトのstdChannel()
の代わりにこのチャネルを
take
およびput
エフェクトに使用します。
例
以下では、Storeに新しいメソッドrunSaga
を追加する関数configureStore
を作成します。次に、メインモジュールで、このメソッドを使用してアプリケーションのルートSagaを開始します。
configureStore.js
import createSagaMiddleware from 'redux-saga'
import reducer from './path/to/reducer'
export default function configureStore(initialState) {
// Note: passing middleware as the last argument to createStore requires redux@>=3.1.0
const sagaMiddleware = createSagaMiddleware()
return {
...createStore(reducer, initialState, applyMiddleware(/* other middleware, */sagaMiddleware)),
runSaga: sagaMiddleware.run
}
}
main.js
import configureStore from './configureStore'
import rootSaga from './sagas'
// ... other imports
const store = configureStore()
store.runSaga(rootSaga)
注記
sagaMiddleware.run
メソッドの詳細については、下記を参照してください。
middleware.run(saga, ...args)
saga
を動的に実行します。applyMiddleware
フェーズ後のみにSagaを実行するために使用できます。
saga: Function
: ジェネレーター関数args: Array<any>
:saga
に提供される引数
このメソッドは、タスク記述子を返します。
注記
saga
は、ジェネレーターオブジェクトを返す関数である必要があります。次に、ミドルウェアはジェネレーターを反復処理し、生成されたすべてのエフェクトを実行します。
saga
は、ライブラリによって提供されるさまざまなエフェクトを使用して、他のSagaを開始することもできます。以下で説明する反復処理は、すべての子Sagaにも適用されます。
最初の反復で、ミドルウェアはnext()
メソッドを呼び出して、次のエフェクトを取得します。次に、ミドルウェアは、以下のエフェクトAPIで指定されているように、生成されたエフェクトを実行します。一方、エフェクトの実行が終了するまで、ジェネレーターは一時停止されます。実行の結果を受け取ると、ミドルウェアはジェネレーターでnext(result)
を呼び出し、取得した結果を引数として渡します。このプロセスは、ジェネレーターが正常に終了するか、何らかのエラーをスローするまで繰り返されます。
実行がエラーになった場合(各エフェクトクリエーターで指定されているように)、代わりにジェネレーターのthrow(error)
メソッドが呼び出されます。ジェネレーター関数が現在のyield命令を囲むtry/catch
を定義している場合、基盤となるジェネレーターランタイムによってcatch
ブロックが呼び出されます。ランタイムは、対応するfinallyブロックも呼び出します。
Sagaがキャンセルされた場合(手動または提供されたエフェクトを使用して)、ミドルウェアはジェネレーターのreturn()
メソッドを呼び出します。これにより、ジェネレーターは直接finallyブロックにスキップします。
エフェクトクリエーター
注記
- 以下の各関数は、プレーンなJavaScriptオブジェクトを返し、実行は行いません。
- 実行は、上記で説明した反復処理中にミドルウェアによって実行されます。
- ミドルウェアは、各エフェクトの説明を調べて、適切なアクションを実行します。
take(pattern)
Storeで指定されたアクションを待機するようにミドルウェアに指示するエフェクトの説明を作成します。pattern
に一致するアクションがディスパッチされるまで、ジェネレーターは一時停止されます。
yield take(pattern)
の結果は、ディスパッチされるアクションオブジェクトです。
pattern
は、次のルールを使用して解釈されます。
引数なしまたは
'*'
でtake
が呼び出された場合、ディスパッチされたすべてのアクションが一致します(例:take()
はすべてのアクションに一致します)。それが関数の場合、
pattern(action)
がtrueの場合、アクションが一致します(例:take(action => action.entities)
は、(真偽値の)entities
フィールドを持つすべてのアクションに一致します)。注:パターン関数に
toString
が定義されている場合、代わりにaction.type
がpattern.toString()
に対してテストされます。これは、redux-actやredux-actionsなどのアクションクリエーターライブラリを使用している場合に役立ちます。文字列の場合、
action.type === pattern
の場合、アクションが一致します(例:take(INCREMENT_ASYNC)
)。配列の場合、配列内の各項目は前述のルールと一致するため、文字列と関数述語の混在配列がサポートされます。最も一般的なユースケースは文字列の配列であるため、
action.type
は配列内のすべての項目と照合されます(例:take([INCREMENT, DECREMENT])
。これは、INCREMENT
またはDECREMENT
型のいずれかのアクションに一致します)。
ミドルウェアは、特別なアクションEND
を提供します。ENDアクションをディスパッチすると、指定されたパターンに関係なく、takeエフェクトでブロックされたすべてのSagaが終了します。終了したSagaにまだ実行中のフォークされたタスクがある場合、すべてのタスクが終了するのを待ってからタスクを終了します。
takeMaybe(pattern)
take(pattern)
と同じですが、END
アクションでSagaを自動的に終了しません。代わりに、takeエフェクトでブロックされたすべてのSagaがEND
オブジェクトを取得します。
注記
takeMaybe
は、FPのアナロジーからその名前が付けられました。ACTION
(自動処理付き)の戻り値の型を持つ代わりに、Maybe(ACTION)
の型を持つことができるようなものです。これにより、両方のケースを処理できます。
Just(ACTION)
がある場合(アクションがある場合)NOTHING
の場合(チャネルが閉じられた*)。つまり、END
をマッピングする何らかの方法が必要です。
- 内部的には、
dispatch
されたすべてのアクションはstdChannel
を通過しており、dispatch(END)
が発生すると閉じられます。
take(channel)
ミドルウェアに、提供されたチャネルからの指定されたメッセージを待機するように指示するエフェクトの説明を作成します。チャネルが既に閉じられている場合、ジェネレーターはtake(pattern)
について上記で説明したのと同じプロセスに従ってすぐに終了します。
takeMaybe(channel)
take(channel)
と同じですが、END
アクションでSagaを自動的に終了しません。代わりに、takeエフェクトでブロックされたすべてのSagaがEND
オブジェクトを取得します。詳細については、こちらを参照してください。
takeEvery(pattern, saga, ...args)
Storeにディスパッチされたpattern
に一致する各アクションでsaga
を生成します。
pattern: String | Array | Function
- 詳細については、take(pattern)
のドキュメントを参照してください。saga: Function
- ジェネレーター関数args: Array<any>
- 開始されたタスクに渡される引数。takeEvery
は、受信したアクションを引数リストに追加します(つまり、アクションはsaga
に提供される最後の引数になります)。
例
次の例では、基本的なタスクfetchUser
を作成します。ディスパッチされた各USER_REQUESTED
アクションで新しいfetchUser
タスクを開始するために、takeEvery
を使用します。
import { takeEvery } from `redux-saga/effects`
function* fetchUser(action) {
...
}
function* watchFetchUser() {
yield takeEvery('USER_REQUESTED', fetchUser)
}
注記
takeEvery
は、take
とfork
を使用して構築された高レベルのAPIです。以下は、低レベルのエフェクトを使用してヘルパーを実装する方法です。
const takeEvery = (patternOrChannel, saga, ...args) => fork(function*() {
while (true) {
const action = yield take(patternOrChannel)
yield fork(saga, ...args.concat(action))
}
})
takeEvery
を使用すると、同時アクションを処理できます。上記の例では、USER_REQUESTED
アクションがディスパッチされると、前のfetchUser
がまだ保留中の場合でも、新しいfetchUser
タスクが開始されます(たとえば、ユーザーがLoad User
ボタンを連続して2回クリックした場合、最初のクリックで起動したfetchUser
がまだ終了していないときに、2回目のクリックでUSER_REQUESTED
アクションがディスパッチされます)。
takeEvery
は、タスクからの順不同のレスポンスを処理しません。タスクが開始された順序で終了するという保証はありません。順不同のレスポンスを処理するには、以下の takeLatest
を検討してください。
takeEvery(channel, saga, ...args)
引数としてチャンネルを渡すこともでき、動作は takeEvery(pattern, saga, ...args) と同じです。
takeLatest(pattern, saga, ...args)
ストアにディスパッチされたアクションが pattern
に一致するたびに、saga
をフォークします。また、以前に開始された saga
タスクがまだ実行中の場合は、自動的にキャンセルします。
アクションがストアにディスパッチされるたびに、このアクションが pattern
に一致する場合、takeLatest
はバックグラウンドで新しい saga
タスクを開始します。以前(実際のアクションの前にディスパッチされた最後のアクションで)saga
タスクが開始され、このタスクがまだ実行中の場合、タスクはキャンセルされます。
pattern: String | Array | Function
- 詳細については、take(pattern)
のドキュメントを参照してください。saga: Function
- ジェネレーター関数args: Array<any>
- 開始されたタスクに渡される引数。takeLatest
は、受信したアクションを引数リストに追加します(つまり、アクションはsaga
に提供される最後の引数になります)。
例
次の例では、基本的なタスク fetchUser
を作成します。takeLatest
を使用して、ディスパッチされた各 USER_REQUESTED
アクションで新しい fetchUser
タスクを開始します。takeLatest
は以前に開始された保留中のタスクをキャンセルするため、ユーザーが複数の連続した USER_REQUESTED
アクションを急速にトリガーした場合でも、最後のアクションで終了するようにします。
import { takeLatest } from `redux-saga/effects`
function* fetchUser(action) {
...
}
function* watchLastFetchUser() {
yield takeLatest('USER_REQUESTED', fetchUser)
}
注記
takeLatest
は、take
と fork
を使用して構築された高レベル API です。以下は、低レベルのエフェクトを使用してヘルパーを実装する方法です。
const takeLatest = (patternOrChannel, saga, ...args) => fork(function*() {
let lastTask
while (true) {
const action = yield take(patternOrChannel)
if (lastTask) {
yield cancel(lastTask) // cancel is no-op if the task has already terminated
}
lastTask = yield fork(saga, ...args.concat(action))
}
})
takeLatest(channel, saga, ...args)
引数としてチャンネルを渡すこともでき、動作は takeLatest(pattern, saga, ...args) と同じです。
takeLeading(pattern, saga, ...args)
ストアにディスパッチされたアクションが pattern
に一致するたびに、saga
を生成します。タスクを一度生成した後、生成された saga が完了するまでブロックし、その後、再び pattern
をリッスンし始めます。
つまり、takeLeading
は saga を実行していないときにアクションをリッスンしています。
pattern: String | Array | Function
- 詳細については、take(pattern)
のドキュメントを参照してください。saga: Function
- ジェネレーター関数args: Array<any>
- 開始されたタスクに渡される引数。takeLeading
は、受信したアクションを引数リストに追加します(つまり、アクションはsaga
に提供される最後の引数になります)。
例
次の例では、基本的なタスク fetchUser
を作成します。takeLeading
を使用して、ディスパッチされた各 USER_REQUESTED
アクションで新しい fetchUser
タスクを開始します。takeLeading
は開始後の新しいタスクを無視するため、ユーザーが複数の連続した USER_REQUESTED
アクションを急速にトリガーした場合でも、先頭のアクションを実行し続けるようにします。
import { takeLeading } from `redux-saga/effects`
function* fetchUser(action) {
...
}
function* watchLastFetchUser() {
yield takeLeading('USER_REQUESTED', fetchUser)
}
注記
takeLeading
は、take
と call
を使用して構築された高レベル API です。以下は、低レベルのエフェクトを使用してヘルパーを実装する方法です。
const takeLeading = (patternOrChannel, saga, ...args) => fork(function*() {
while (true) {
const action = yield take(patternOrChannel);
yield call(saga, ...args.concat(action));
}
})
takeLeading(channel, saga, ...args)
引数としてチャンネルを渡すこともでき、動作は takeLeading(pattern, saga, ...args) と同じです。
put(action)
ストアへのアクションのディスパッチをスケジュールするようにミドルウェアに指示するエフェクト記述を作成します。他のタスクが saga タスクキューで先頭にあるか、まだ進行中の可能性があるため、このディスパッチは即時ではない場合があります。
ただし、非同期フローを持つ他の Redux ミドルウェアがアクションの伝播を遅延させていない限り、ストアが現在のスタックフレームで(つまり、yield put(action)
の次のコード行で)更新されることを期待できます。
ダウンストリームのエラー(例:リデューサーからのエラー)は、バブルアップされます。
action: Object
- 完全な情報については、Reduxdispatch
ドキュメントを参照してください
putResolve(action)
put
と同様ですが、エフェクトはブロッキングです(promise が dispatch
から返される場合、その解決を待機します)ダウンストリームからのエラーをバブルアップします。
action: Object
- 完全な情報については、Reduxdispatch
ドキュメントを参照してください
put(channel, action)
提供されたチャンネルにアクションを put するようにミドルウェアに指示するエフェクト記述を作成します。
channel: Channel
-Channel
オブジェクト。action: Object
- 完全な情報については、Reduxdispatch
ドキュメントを参照してください
このエフェクトは、put がバッファリングされず、taker によってすぐに消費される場合は、ブロッキングです。これらの taker のいずれかでエラーがスローされた場合、saga にバブルバックされます。
call(fn, ...args)
fn
関数を引数として args
を使用して呼び出すようにミドルウェアに指示するエフェクト記述を作成します。
fn: Function
- ジェネレーター関数、または Promise を結果として返すか、その他の値を返す通常の関数。args: Array<any>
-fn
に引数として渡される値の配列
注記
fn
は、通常の関数またはジェネレーター関数にすることができます。
ミドルウェアは関数を呼び出し、その結果を調べます。
結果がイテレーターオブジェクトの場合、ミドルウェアは(起動時にミドルウェアに渡された)起動ジェネレーターと同じように、そのジェネレーター関数を実行します。親ジェネレーターは、子ジェネレーターが正常に終了するまで中断され、その場合、親ジェネレーターは子ジェネレーターによって返された値で再開されます。または、子ジェネレーターがエラーで中断するまで、その場合、エラーは親ジェネレーター内でスローされます。
fn
が通常の関数であり、Promise を返す場合、ミドルウェアは Promise が解決するまでジェネレーターを中断します。Promise が解決されると、ジェネレーターは解決された値で再開されるか、Promise が拒否された場合は、ジェネレーター内でエラーがスローされます。
結果がイテレーターオブジェクトでも Promise でもない場合、ミドルウェアはすぐにその値を saga に返して、同期的に実行を再開できるようにします。
ジェネレーター内でエラーがスローされた場合、現在の yield
命令を囲む try/catch
ブロックがある場合、制御は catch
ブロックに渡されます。それ以外の場合、ジェネレーターは発生したエラーで中断し、このジェネレーターが別のジェネレーターによって呼び出された場合、エラーは呼び出し側のジェネレーターに伝播します。
call([context, fn], ...args)
call(fn, ...args)
と同じですが、fn
に this
コンテキストを渡すことをサポートします。これは、オブジェクトメソッドを呼び出すのに便利です。
call([context, fnName], ...args)
call([context, fn], ...args)
と同じですが、文字列として fn
を渡すことをサポートします。オブジェクトのメソッドを呼び出すのに便利です。例:yield call([localStorage, 'getItem'], 'redux-saga')
call({context, fn}, ...args)
call([context, fn], ...args)
と同じですが、オブジェクトのプロパティとして context
と fn
を渡すことをサポートします。例:yield call({context: localStorage, fn: localStorage.getItem}, 'redux-saga')
。 fn
は文字列または関数にすることができます。
apply(context, fn, [args])
call([context, fn], ...args)
のエイリアス。
cps(fn, ...args)
fn
を Node スタイルの関数として呼び出すようにミドルウェアに指示するエフェクト記述を作成します。
fn: Function
- Node スタイルの関数。つまり、引数に加えて、fn
が終了したときに呼び出す追加のコールバックを受け入れる関数。コールバックは 2 つのパラメーターを受け入れ、最初のパラメーターはエラーを報告するために使用され、2 番目のパラメーターは成功した結果を報告するために使用されますargs: Array<any>
-fn
の引数として渡される配列
注記
ミドルウェアは、fn(...arg, cb)
を呼び出します。cb
は、ミドルウェアによって fn
に渡されるコールバックです。fn
が正常に終了した場合、成功した結果をミドルウェアに通知するために cb(null, result)
を呼び出す必要があります。fn
でエラーが発生した場合は、エラーが発生したことをミドルウェアに通知するために cb(error)
を呼び出す必要があります。
ミドルウェアは、fn
が終了するまで中断されたままになります。
cps([context, fn], ...args)
fn
に this
コンテキストを渡すことをサポートします(オブジェクトメソッドの呼び出し)。
cps({context, fn}, ...args)
cps([context, fn], ...args)
と同じですが、オブジェクトのプロパティとして context
と fn
を渡すことをサポートします。 fn
は文字列または関数にすることができます。
fork(fn, ...args)
fn
で非ブロッキング呼び出しを実行するようにミドルウェアに指示するエフェクト記述を作成します。
引数
fn: Function
- ジェネレーター関数、または Promise を結果として返す通常の関数args: Array<any>
-fn
に引数として渡される値の配列
Task オブジェクトを返します。
注記
fork
は、call
と同様に、通常の関数とジェネレーター関数の両方を呼び出すために使用できます。ただし、呼び出しはノンブロッキングであり、ミドルウェアは fn
の結果を待っている間、ジェネレーターを中断しません。代わりに、fn
が呼び出されるとすぐに、ジェネレーターはすぐに再開します。
fork
は、race
と並んで、Saga 間の並行処理を管理するための中心的な Effect です。
yield fork(fn ...args)
の結果は、Task オブジェクトです。これは、いくつかの便利なメソッドとプロパティを持つオブジェクトです。
フォークされたすべてのタスクは、その親にアタッチされています。親が自身の命令本体の実行を終了すると、フォークされたすべてのタスクが終了するのを待ってから返ります。
エラー伝播
子タスクからのエラーは、自動的に親にバブルアップします。フォークされたタスクでキャッチされないエラーが発生した場合、親タスクは子エラーで中止され、親の実行ツリー全体(つまり、フォークされたタスクと、親の本体がまだ実行中の場合は親の本体によって表されるメインタスク)がキャンセルされます。
フォークされたタスクのキャンセルは、実行中のすべてのフォークされたタスクを自動的にキャンセルします。また、キャンセルされたタスクがブロックされていた現在の Effect もキャンセルされます(存在する場合)。
フォークされたタスクが同期的に失敗した場合(つまり、非同期操作を実行する前に実行直後に失敗した場合)、Task は返されず、代わりに親は可能な限り早く中止されます(親と子の両方が並行して実行されるため、親は子の失敗に気づくとすぐに中止されます)。
デタッチされたフォークを作成するには、代わりに spawn
を使用します。
fork([context, fn], ...args)
this
コンテキストを使用してフォークされた関数を呼び出すことをサポートします。
fork({context, fn}, ...args)
fork([context, fn], ...args)
と同様ですが、context
と fn
をオブジェクトのプロパティとして渡すことをサポートします。fn
は文字列または関数にすることができます。
spawn(fn, ...args)
fork(fn, ...args)
と同様ですが、デタッチされたタスクを作成します。デタッチされたタスクは、その親から独立しており、トップレベルのタスクのように動作します。親は、デタッチされたタスクが終了するのを待たずに返り、親またはデタッチされたタスクに影響を与える可能性のあるすべてのイベントは完全に独立しています(エラー、キャンセル)。
spawn([context, fn], ...args)
this
コンテキストを使用して関数をスポーンすることをサポートします。
join(task)
ミドルウェアに、以前にフォークされたタスクの結果を待つように指示する Effect の記述を作成します。
task: Task
- 以前のfork
によって返された Task オブジェクト
注釈
join
は、結合されたタスクの同じ結果(成功またはエラー)に解決されます。結合されたタスクがキャンセルされた場合、キャンセルは join エフェクトを実行している Saga にも伝播します。同様に、それらの joiner の潜在的な呼び出し元もキャンセルされます。
join([...tasks])
ミドルウェアに、以前にフォークされたタスクの結果を待つように指示する Effect の記述を作成します。
tasks: Array<Task>
- Task は、以前のfork
によって返されるオブジェクトです
注釈
これはタスクの配列を join エフェクトでラップし、おおまかに yield tasks.map(t => join(t))
と同等になります。
cancel(task)
ミドルウェアに、以前にフォークされたタスクをキャンセルするように指示する Effect の記述を作成します。
task: Task
- 以前のfork
によって返された Task オブジェクト
注釈
実行中のタスクをキャンセルするために、ミドルウェアは基になるジェネレーターオブジェクトで return
を呼び出します。これにより、タスク内の現在の Effect がキャンセルされ、(定義されている場合は)finally ブロックにジャンプします。
finally ブロック内では、クリーンアップロジックを実行したり、ストアを一貫した状態に保つためのアクションをディスパッチしたりできます(たとえば、ajax リクエストがキャンセルされたときにスピナーの状態を false にリセットするなど)。yield cancelled()
を発行することで、finally ブロック内で Saga がキャンセルされたかどうかを確認できます。
キャンセルは、子 saga に下方向に伝播します。タスクをキャンセルすると、ミドルウェアは現在の Effect(タスクが現在ブロックされている場所)もキャンセルします。現在の Effect が別の Saga の呼び出しである場合、それもキャンセルされます。Saga をキャンセルすると、すべてのアタッチされたフォーク(yield fork()
を使用してフォークされた saga)がキャンセルされます。これは、キャンセルが、キャンセルされたタスクに属する実行ツリー全体に効果的に影響することを意味します。
cancel
はノンブロッキングな Effect です。つまり、それを実行する Saga は、キャンセルを実行した後すぐに再開します。
Promise の結果を返す関数の場合、Promise に [CANCEL]
をアタッチすることで、独自のキャンセルロジックをプラグインできます。
次の例は、Promise の結果にキャンセルロジックをアタッチする方法を示しています。
import { CANCEL } from 'redux-saga'
import { fork, cancel } from 'redux-saga/effects'
function myApi() {
const promise = myXhr(...)
promise[CANCEL] = () => myXhr.abort()
return promise
}
function* mySaga() {
const task = yield fork(myApi)
// ... later
// will call promise[CANCEL] on the result of myApi
yield cancel(task)
}
redux-saga は、abort
メソッドを使用して jqXHR オブジェクトを自動的にキャンセルします。
cancel([...tasks])
ミドルウェアに、以前にフォークされたタスクをキャンセルするように指示する Effect の記述を作成します。
tasks: Array<Task>
- Task は、以前のfork
によって返されるオブジェクトです
注釈
これはタスクの配列を cancel エフェクトでラップし、おおまかに yield tasks.map(t => cancel(t))
と同等になります。
cancel()
ミドルウェアに、それが yield されたタスクをキャンセルするように指示する Effect の記述を作成します(自己キャンセル)。これにより、外部(cancel(task)
)と自己(cancel()
)の両方のキャンセルに対して、finally
ブロック内でデストラクターのようなロジックを再利用できます。
例
function* deleteRecord({ payload }) {
try {
const { confirm, deny } = yield call(prompt);
if (confirm) {
yield put(actions.deleteRecord.confirmed())
}
if (deny) {
yield cancel()
}
} catch(e) {
// handle failure
} finally {
if (yield cancelled()) {
// shared cancellation logic
yield put(actions.deleteRecord.cancel(payload))
}
}
}
select(selector, ...args)
ミドルウェアに、現在のストアの状態に対して提供されたセレクターを呼び出すように指示するエフェクトを作成します(つまり、selector(getState(), ...args)
の結果を返します)。
selector: Function
- 関数(state, ...args) => args
。現在の状態とオプションでいくつかの引数を取り、現在のストアの状態の一部を返しますargs: Array<any>
-getState
に加えて、セレクターに渡されるオプションの引数。
select
が引数なしで呼び出された場合(つまり、yield select()
)、エフェクトは状態全体(getState()
呼び出しと同じ結果)で解決されます。
アクションがストアにディスパッチされると、ミドルウェアは最初にアクションをリデューサーに転送し、次に Saga に通知することに注意することが重要です。これは、ストアの状態をクエリすると、アクションが適用された後の状態を取得することを意味します。ただし、この動作は、後続のすべてのミドルウェアが
next(action)
を同期的に呼び出す場合にのみ保証されます。後続のミドルウェアがnext(action)
を非同期的に呼び出す場合(これは珍しいことですが可能)、saga はアクションが適用される前の状態を取得します。したがって、後続の各ミドルウェアのソースを確認して、next(action)
を同期的に呼び出すことを確認するか、redux-saga がコールチェーンの最後のミドルウェアであることを確認することをお勧めします。
注釈
できれば、Saga は自律的であるべきであり、ストアの状態に依存すべきではありません。これにより、Saga コードに影響を与えることなく、状態の実装を簡単に変更できます。saga は、可能な限り、独自の内部制御状態のみに依存する必要があります。ただし、Saga が必要なデータを自身で維持する代わりに、ストアの状態をクエリする方が便利な場合があります(たとえば、Saga がストアによって既に計算された状態を計算するために、一部のリデューサーを呼び出すロジックを複製する場合など)。
たとえば、アプリケーションに次の状態形状があるとします
state = {
cart: {...}
}
セレクター、つまり状態から cart
データを抽出する方法を知っている関数を作成できます
./selectors
export const getCart = state => state.cart
次に、select
エフェクトを使用して、Saga 内からそのセレクターを使用できます
./sagas.js
import { take, fork, select } from 'redux-saga/effects'
import { getCart } from './selectors'
function* checkout() {
// query the state using the exported selector
const cart = yield select(getCart)
// ... call some API endpoint then dispatch a success/error action
}
export default function* rootSaga() {
while (true) {
yield take('CHECKOUT_REQUEST')
yield fork(checkout)
}
}
checkout
は、select(getCart)
を使用して、必要な情報を直接取得できます。Saga は getCart
セレクターのみと結合されています。cart
スライスにアクセスする必要がある Saga(または React コンポーネント)が多数ある場合、それらはすべて同じ関数 getCart
と結合されます。そして、状態形状を変更する場合、getCart
を更新するだけで済みます。
actionChannel(pattern, [buffer])
ミドルウェアに、イベントチャネルを使用して pattern
に一致するアクションをキューに入れるように指示するエフェクトを作成します。オプションで、キューに入れられたアクションのバッファリングを制御するためのバッファを提供できます。
pattern:
-take(pattern)
の API を参照buffer: Buffer
- Buffer オブジェクト
例
次のコードは、すべての USER_REQUEST
アクションをバッファリングするためのチャネルを作成します。Saga が call
エフェクトでブロックされている場合でも、すべてのブロックされている間に発生するアクションは自動的にバッファリングされます。これにより、Saga は API 呼び出しを一度に 1 つずつ実行します。
import { actionChannel, call } from 'redux-saga/effects'
import api from '...'
function* takeOneAtMost() {
const chan = yield actionChannel('USER_REQUEST')
while (true) {
const {payload} = yield take(chan)
yield call(api.getUser, payload)
}
}
flush(channel)
ミドルウェアに、チャネルからバッファリングされたすべてのアイテムをフラッシュするように指示するエフェクトを作成します。フラッシュされたアイテムは Saga に返されるため、必要に応じて利用できます。
channel: Channel
-Channel
オブジェクト。
例
function* saga() {
const chan = yield actionChannel('ACTION')
try {
while (true) {
const action = yield take(chan)
// ...
}
} finally {
const actions = yield flush(chan)
// ...
}
}
cancelled()
ミドルウェアに、このジェネレーターがキャンセルされたかどうかを返すように指示するエフェクトを作成します。通常、このエフェクトは finally ブロックで使用して、キャンセル固有のコードを実行します。
例
function* saga() {
try {
// ...
} finally {
if (yield cancelled()) {
// logic that should execute only on Cancellation
}
// logic that should execute in all situations (e.g. closing a channel)
}
}
setContext(props)
ミドルウェアに自身のコンテキストを更新するように指示するエフェクトを作成します。このエフェクトは、sagaのコンテキストを置き換えるのではなく、拡張します。
getContext(prop)
ミドルウェアにsagaのコンテキストの特定のプロパティを返すように指示するエフェクトを作成します。
delay(ms, [val])
実行をms
ミリ秒間ブロックし、val
値を返すエフェクト記述子を返します。
throttle(ms, pattern, saga, ...args)
pattern
に一致するStoreにディスパッチされたアクションに対してsaga
を生成します。タスクを生成した後も、基盤となるbuffer
に受信アクションを受け入れ、最大1つ(最新のもの)を保持しますが、同時にms
ミリ秒間新しいタスクの生成を保留します(したがって、その名前はthrottle
です)。この目的は、タスクを処理中に、指定された期間、受信アクションを無視することです。
ms: Number
- アクションの処理開始後にアクションが無視される時間枠の長さ(ミリ秒単位)pattern: String | Array | Function
- 詳細については、take(pattern)
のドキュメントを参照してください。saga: Function
- ジェネレーター関数args: Array<any>
- 開始されたタスクに渡される引数。throttle
は、受信アクションを引数リストに追加します(つまり、アクションはsaga
に提供される最後の引数になります)。
例
次の例では、基本的なタスクfetchAutocomplete
を作成します。ディスパッチされたFETCH_AUTOCOMPLETE
アクションで新しいfetchAutocomplete
タスクを開始するためにthrottle
を使用します。ただし、throttle
は連続するFETCH_AUTOCOMPLETE
をしばらく無視するため、ユーザーがサーバーにリクエストを殺到させないようにします。
import { call, put, throttle } from `redux-saga/effects`
function* fetchAutocomplete(action) {
const autocompleteProposals = yield call(Api.fetchAutocomplete, action.text)
yield put({type: 'FETCHED_AUTOCOMPLETE_PROPOSALS', proposals: autocompleteProposals})
}
function* throttleAutocomplete() {
yield throttle(1000, 'FETCH_AUTOCOMPLETE', fetchAutocomplete)
}
注釈
throttle
は、take
、fork
、およびactionChannel
を使用して構築された高レベルのAPIです。低レベルのエフェクトを使用してヘルパーを実装する方法は次のとおりです。
const throttle = (ms, pattern, task, ...args) => fork(function*() {
const throttleChannel = yield actionChannel(pattern, buffers.sliding(1))
while (true) {
const action = yield take(throttleChannel)
yield fork(task, ...args, action)
yield delay(ms)
}
})
throttle(ms, channel, saga, ...args)
引数としてチャネルを処理することもでき、動作はthrottle(ms, pattern, saga, ..args)
と同じです。
debounce(ms, pattern, saga, ...args)
pattern
に一致するStoreにディスパッチされたアクションに対してsaga
を生成します。Sagaは、ms
ミリ秒間pattern
アクションの取得を停止した後に呼び出されます。この目的は、アクションが落ち着くまでsagaの呼び出しを防止することです。
ms: Number
-saga
を呼び出すために、最後にpattern
アクションが発行されてから経過するミリ秒数を定義します。pattern: String | Array | Function
- 詳細については、take(pattern)
のドキュメントを参照してください。saga: Function
- ジェネレーター関数args: Array<any>
- 開始されたタスクに渡される引数。debounce
は、受信アクションを引数リストに追加します(つまり、アクションはsaga
に提供される最後の引数になります)。
例
次の例では、基本的なタスクfetchAutocomplete
を作成します。debounce
を使用して、少なくとも1000
ミリ秒間FETCH_AUTOCOMPLETE
イベントを受信しなくなるまで、fetchAutocomplete
sagaの呼び出しを遅延させます。
import { call, put, debounce } from `redux-saga/effects`
function* fetchAutocomplete(action) {
const autocompleteProposals = yield call(Api.fetchAutocomplete, action.text)
yield put({type: 'FETCHED_AUTOCOMPLETE_PROPOSALS', proposals: autocompleteProposals})
}
function* debounceAutocomplete() {
yield debounce(1000, 'FETCH_AUTOCOMPLETE', fetchAutocomplete)
}
注釈
debounce
は、take
、delay
、race
、およびfork
を使用して構築された高レベルのAPIです。低レベルのエフェクトを使用してヘルパーを実装する方法は次のとおりです。
const debounce = (ms, pattern, task, ...args) => fork(function*() {
while (true) {
let action = yield take(pattern)
while (true) {
const { debounced, latestAction } = yield race({
debounced: delay(ms),
latestAction: take(pattern)
})
if (debounced) {
yield fork(task, ...args, action)
break
}
action = latestAction
}
}
})
debounce(ms, channel, saga, ...args)
引数としてチャネルを処理することもでき、動作はdebounce(ms, pattern, saga, ..args)
と同じです。
retry(maxTries, delay, fn, ...args)
ミドルウェアに、引数としてargs
を使用して関数fn
を呼び出すように指示するエフェクト記述を作成します。失敗した場合、試行回数がmaxTries
未満の場合、delay
ミリ秒後に別の呼び出しを試みます。
maxTries: Number
- 最大呼び出し回数。delay: Number
-fn
呼び出し間の時間枠の長さ(ミリ秒単位)。fn: Function
- 結果としてPromiseを返すジェネレータ関数、または通常の関数、またはその他の値。args: Array<any>
-fn
に引数として渡される値の配列
例
次の例では、基本的なタスクretrySaga
を作成します。retry
を使用して、APIを10秒間隔で3回フェッチしようとします。request
が最初に失敗した場合、retry
は呼び出し回数が3未満の間、request
をもう一度呼び出します。
import { put, retry } from 'redux-saga/effects'
import { request } from 'some-api';
function* retrySaga(data) {
try {
const SECOND = 1000
const response = yield retry(3, 10 * SECOND, request, data)
yield put({ type: 'REQUEST_SUCCESS', payload: response })
} catch(error) {
yield put({ type: 'REQUEST_FAIL', payload: { error } })
}
}
注釈
retry
は、delay
とcall
を使用して構築された高レベルのAPIです。低レベルのエフェクトを使用してヘルパーを実装する方法は次のとおりです
エフェクトコンビネータ
race(effects)
ミドルウェアに複数のエフェクト間でレースを実行するように指示するエフェクト記述を作成します(これはPromise.race([...])
がどのように動作するかと似ています)。
effects: Object
- {label: effect, ...}形式の辞書オブジェクト
例
次の例では、2つのエフェクト間のレースを実行します
- Promiseを返す関数
fetchUsers
の呼び出し - Storeで最終的にディスパッチされる可能性のある
CANCEL_FETCH
アクション
import { take, call, race } from `redux-saga/effects`
import fetchUsers from './path/to/fetchUsers'
function* fetchUsersSaga() {
const { response, cancel } = yield race({
response: call(fetchUsers),
cancel: take(CANCEL_FETCH)
})
}
call(fetchUsers)
が最初に解決された場合、race
の結果は、{response: result}
という単一のキー付きオブジェクトを持つオブジェクトになります。ここで、result
はfetchUsers
の解決された結果です。
call(fetchUsers)
が最初に拒否された場合、race
は拒否の理由をスローします。
fetchUsers
が完了する前に、タイプCANCEL_FETCH
のアクションがStoreでディスパッチされた場合、結果は単一のキー付きオブジェクト{cancel: action}
になります。ここで、actionはディスパッチされたアクションです。
注釈
race
を解決するとき、ミドルウェアは自動的に負けたすべてのエフェクトをキャンセルします。
race([...effects]) (配列を使用)
race(effects)
と同じですが、エフェクトの配列を渡すことができます。
例
次の例では、2つのエフェクト間のレースを実行します
- Promiseを返す関数
fetchUsers
の呼び出し - Storeで最終的にディスパッチされる可能性のある
CANCEL_FETCH
アクション
import { take, call, race } from `redux-saga/effects`
import fetchUsers from './path/to/fetchUsers'
function* fetchUsersSaga() {
const [response, cancel] = yield race([
call(fetchUsers),
take(CANCEL_FETCH)
])
}
call(fetchUsers)
が最初に解決された場合、response
はfetchUsers
の結果になり、cancel
はundefined
になります。
call(fetchUsers)
が最初に拒否された場合、race
は拒否の理由をスローします。
fetchUsers
が完了する前に、タイプCANCEL_FETCH
のアクションがStoreでディスパッチされた場合、response
はundefined
になり、cancel
はディスパッチされたアクションになります。
all([...effects]) - 並列エフェクト
ミドルウェアに複数のエフェクトを並行して実行し、すべてが完了するのを待つように指示するエフェクト記述を作成します。これは、標準のPromise#all
に対応するAPIです。
例
次の例では、2つのブロッキング呼び出しを並行して実行します
import { fetchCustomers, fetchProducts } from './path/to/api'
import { all, call } from `redux-saga/effects`
function* mySaga() {
const [customers, products] = yield all([
call(fetchCustomers),
call(fetchProducts)
])
}
all(effects)
all([...effects])
と同じですが、race(effects)
と同様に、ラベル付きのエフェクトの辞書オブジェクトを渡すことができます。
effects: Object
- {label: effect, ...}形式の辞書オブジェクト
例
次の例では、2つのブロッキング呼び出しを並行して実行します
import { fetchCustomers, fetchProducts } from './path/to/api'
import { all, call } from `redux-saga/effects`
function* mySaga() {
const { customers, products } = yield all({
customers: call(fetchCustomers),
products: call(fetchProducts)
})
}
注釈
エフェクトを並行して実行すると、ミドルウェアは、次のいずれかが発生するまでジェネレータを中断します
すべてのエフェクトが正常に完了した場合:すべてのエフェクトの結果を含む配列でジェネレータを再開します。
すべてのエフェクトが完了する前に、いずれかのエフェクトが拒否された場合:ジェネレータ内で拒否エラーをスローします。
インターフェース
タスク
タスクインターフェースは、fork
、middleware.run
、またはrunSaga
を使用してSagaを実行した結果を指定します。
メソッド | 戻り値 |
---|---|
task.isRunning() | タスクがまだ返却されていないか、エラーをスローしていない場合はtrue |
task.isCancelled() | タスクがキャンセルされた場合はtrue |
task.result() | タスクの戻り値。タスクがまだ実行中の場合は`undefined` |
task.error() | タスクがスローしたエラー。タスクがまだ実行中の場合は`undefined` |
task.toPromise() | 次のいずれかのPromise
|
task.cancel() | タスクをキャンセルします(まだ実行中の場合) |
チャネル
チャネルは、タスク間でメッセージを送受信するために使用されるオブジェクトです。送信者からのメッセージは、関心のある受信者がメッセージを要求するまでキューに入れられ、登録された受信者はメッセージが利用可能になるまでキューに入れられます。
すべてのチャネルには、バッファリング戦略(固定サイズ、ドロップ、スライディング)を定義する基盤となるバッファがあります
チャネルインターフェースは、3つのメソッドtake
、put
、およびclose
を定義します
Channel.take(callback):
テイカーを登録するために使用されます。takeは次のルールを使用して解決されます
- チャネルにバッファリングされたメッセージがある場合、
callback
は基盤となるバッファからの次のメッセージ(buffer.take()
を使用)で呼び出されます - チャネルが閉じられており、バッファリングされたメッセージがない場合、
callback
はEND
で呼び出されます - それ以外の場合、
callback
はメッセージがチャネルにプットされるまでキューに入れられます
Channel.put(message):
バッファにメッセージをプットするために使用されます。putは次のルールを使用して処理されます
- チャネルが閉じられている場合、putは効果がありません。
- 保留中のテイカーがある場合は、メッセージで最も古いテイカーを呼び出します。
- それ以外の場合は、基盤となるバッファにメッセージをプットします
Channel.flush(callback):
チャネルからすべてのバッファリングされたメッセージを抽出するために使用されます。flushは次のルールを使用して解決されます
- チャネルが閉じられており、バッファリングされたメッセージがない場合、
callback
はEND
で呼び出されます - それ以外の場合、
callback
はすべてのバッファリングされたメッセージで呼び出されます。
Channel.close():
チャネルを閉じます。つまり、これ以上のputは許可されません。すべての保留中のテイカーはEND
で呼び出されます。
バッファ
チャネルのバッファリング戦略を実装するために使用されます。バッファインターフェースは、3つのメソッドisEmpty
、put
、およびtake
を定義します
isEmpty()
:バッファにメッセージがない場合はtrueを返します。チャネルは、新しいテイカーが登録されるたびにこのメソッドを呼び出しますput(message)
: バッファに新しいメッセージを格納するために使用されます。バッファはメッセージを格納しない場合があることに注意してください(例:ドロップバッファは指定された制限を超える新しいメッセージをドロップできます)。take()
: バッファリングされたメッセージを取得するために使用されます。このメソッドの動作はisEmpty
と一貫性がある必要があることに注意してください。
SagaMonitor
ミドルウェアが監視イベントをディスパッチするために使用します。実際には、ミドルウェアは6つのイベントをディスパッチします。
ルート Saga が開始されると (
runSaga
またはsagaMiddleware.run
を介して)、ミドルウェアはsagaMonitor.rootSagaStarted
を呼び出します。エフェクトがトリガーされると (
yield someEffect
を介して)、ミドルウェアはsagaMonitor.effectTriggered
を呼び出します。エフェクトが成功で解決されると、ミドルウェアは
sagaMonitor.effectResolved
を呼び出します。エフェクトがエラーでリジェクトされると、ミドルウェアは
sagaMonitor.effectRejected
を呼び出します。エフェクトがキャンセルされると、ミドルウェアは
sagaMonitor.effectCancelled
を呼び出します。最後に、Redux アクションがディスパッチされると、ミドルウェアは
sagaMonitor.actionDispatched
を呼び出します。
以下に、各メソッドの署名を示します。
sagaMonitor.rootSagaStarted(options)
: options は次のフィールドを持つオブジェクトです。effectId
: Number - このルート Saga の実行に割り当てられた一意の IDsaga
: Function - 実行を開始するジェネレータ関数args
: Array - ジェネレータ関数に渡された引数
effectTriggered(options)
effectId
: Number - 生成されたエフェクトに割り当てられた一意の IDparentEffectId
: Number - 親エフェクトの ID。race
またはparallel
エフェクトの場合、内部で生成されたすべてのエフェクトは、直接の race/parallel エフェクトを親として持ちます。トップレベルのエフェクトの場合、親は包含する Saga になります。label
: String -race
/all
エフェクトの場合、すべての子エフェクトには、race
/all
に渡されたオブジェクトの対応するキーがラベルとして割り当てられます。effect
: Object - 生成されたエフェクト自体
effectResolved(effectId, result)
effectId
: Number - 生成されたエフェクトの IDresult
: any - エフェクトの正常な解決の結果。fork
またはspawn
エフェクトの場合、結果はTask
オブジェクトになります。
effectRejected(effectId, error)
effectId
: Number - 生成されたエフェクトの IDerror
: any - エフェクトのリジェクトで発生したエラー
effectCancelled(effectId)
effectId
: Number - 生成されたエフェクトの ID
actionDispatched(action)
action
: Object - ディスパッチされた Redux アクション。アクションが Saga によってディスパッチされた場合、アクションにはSAGA_ACTION
プロパティが true に設定されます (SAGA_ACTION
は@redux-saga/symbols
からインポートできます)。
外部 API
runSaga(options, saga, ...args)
Redux ミドルウェア環境の外で Saga を開始できるようにします。ストアアクション以外の外部入力/出力に Saga を接続したい場合に便利です。
runSaga
は Task オブジェクトを返します。fork
エフェクトから返されるものと同様です。
options: Object
- 現在サポートされているオプションは次のとおりです。channel
-channel
のドキュメントを参照してください (ここではstdChannel
を使用することをお勧めします)。dispatch(output): Function
-put
エフェクトを満たすために使用されます。output: any
- Saga によってput
エフェクトに提供される引数 (以下の注を参照)。
getState(): Function
-select
およびgetState
エフェクトを満たすために使用されます。sagaMonitor
: SagaMonitor -createSagaMiddleware(options)
のドキュメントを参照してください。onError: Function
-createSagaMiddleware(options)
のドキュメントを参照してください。context
: {} -createSagaMiddleware(options)
のドキュメントを参照してください。effectMiddlewares
: Function[] -createSagaMiddleware(options)
のドキュメントを参照してください。
saga: Function
- ジェネレーター関数args: Array<any>
-saga
に提供される引数
注
{channel, dispatch}
は、take
および put
エフェクトを満たすために使用されます。これは、Saga の入出力インターフェイスを定義します。
channel
は、take(PATTERN)
エフェクトを満たすために使用されます。何かがチャネルに投入されるたびに、保留中の内部リスナーすべてに通知されます。Saga が take
エフェクトでブロックされている場合、および take パターンが現在着信中の入力と一致する場合、Saga はその入力で再開されます。
dispatch
は、put
エフェクトを満たすために使用されます。Saga が yield put(output)
を出力するたびに、dispatch
が output で呼び出されます。
この API の使用方法の例は、こちらで確認できます。
ユーティリティ
channel([buffer])
チャネルを作成するために使用できるファクトリメソッド。オプションで、チャネルがメッセージをバッファリングする方法を制御するためのバッファを渡すことができます。
デフォルトでは、バッファが提供されない場合、チャネルは、関心のあるテーカーが登録されるまで、着信メッセージを最大 10 個までキューに入れます。デフォルトのバッファリングは、FIFO ストラテジーを使用してメッセージを配信します。新しいテーカーには、バッファ内の最も古いメッセージが配信されます。
eventChannel(subscribe, [buffer])
subscribe
メソッドを使用してイベントソースをサブスクライブするチャネルを作成します。イベントソースからの着信イベントは、関心のあるテーカーが登録されるまでチャネルでキューに入れられます。
subscribe: Function
基になるイベントソースをサブスクライブするために使用されます。関数は、サブスクリプションを終了するためのアンサブスクライブ関数を返す必要があります。buffer: Buffer
オプションの Buffer オブジェクト。このチャネルでメッセージをバッファリングします。指定しない場合、メッセージはこのチャネルでバッファリングされません。
イベントソースが終了したことをチャネルに通知するには、提供されたサブスクライバーに END
を通知できます。
例
次の例では、setInterval
をサブスクライブするイベントチャネルを作成します。
const countdown = (secs) => {
return eventChannel(emitter => {
const iv = setInterval(() => {
console.log('countdown', secs)
secs -= 1
if (secs > 0) {
emitter(secs)
} else {
emitter(END)
clearInterval(iv)
console.log('countdown terminated')
}
}, 1000);
return () => {
clearInterval(iv)
console.log('countdown cancelled')
}
}
)
}
buffers
いくつかの一般的なバッファを提供します。
buffers.none()
: バッファリングなし。保留中のテーカーがない場合、新しいメッセージは失われます。buffers.fixed(limit)
: 新しいメッセージはlimit
までバッファリングされます。オーバーフローするとエラーが発生します。limit
値を省略すると、制限は 10 になります。buffers.expanding(initialSize)
:fixed
と同様ですが、オーバーフローするとバッファが動的に拡張されます。buffers.dropping(limit)
:fixed
と同じですが、オーバーフローするとメッセージがサイレントにドロップされます。buffers.sliding(limit)
:fixed
と同じですが、オーバーフローすると、新しいメッセージが最後に追加され、バッファ内の最も古いメッセージがドロップされます。
cloneableGenerator(generatorFunc)
ジェネレータ関数 (function*) を受け取り、ジェネレータ関数を返します。この関数からインスタンス化されたすべてのジェネレータは複製可能になります。テスト目的のみに使用します。
例
これは、それに至るアクションを再生することなく、Saga の別のブランチをテストしたい場合に便利です。
import { cloneableGenerator } from '@redux-saga/testing-utils';
function* oddOrEven() {
// some stuff are done here
yield 1;
yield 2;
yield 3;
const userInput = yield 'enter a number';
if (userInput % 2 === 0) {
yield 'even';
} else {
yield 'odd'
}
}
test('my oddOrEven saga', assert => {
const data = {};
data.gen = cloneableGenerator(oddOrEven)();
assert.equal(
data.gen.next().value,
1,
'it should yield 1'
);
assert.equal(
data.gen.next().value,
2,
'it should yield 2'
);
assert.equal(
data.gen.next().value,
3,
'it should yield 3'
);
assert.equal(
data.gen.next().value,
'enter a number',
'it should ask for a number'
);
assert.test('even number is given', a => {
// we make a clone of the generator before giving the number;
data.clone = data.gen.clone();
a.equal(
data.gen.next(2).value,
'even',
'it should yield "even"'
);
a.equal(
data.gen.next().done,
true,
'it should be done'
);
a.end();
});
assert.test('odd number is given', a => {
a.equal(
data.clone.next(1).value,
'odd',
'it should yield "odd"'
);
a.equal(
data.clone.next().done,
true,
'it should be done'
);
a.end();
});
assert.end();
});
createMockTask()
タスクをモックするオブジェクトを返します。テスト目的のみに使用します。詳細については、タスクキャンセルに関するドキュメントを参照してください。)
チートシート
ブロッキング/非ブロッキング
名前 | ブロッキング |
---|---|
takeEvery | いいえ |
takeLatest | いいえ |
takeLeading | いいえ |
throttle | いいえ |
debounce | いいえ |
retry | はい |
take | はい |
take(channel) | 場合による (API リファレンスを参照) |
takeMaybe | はい |
put | いいえ |
putResolve | はい |
put(channel, action) | いいえ |
call | はい |
apply | はい |
cps | はい |
fork | いいえ |
spawn | いいえ |
join | はい |
cancel | いいえ |
select | いいえ |
actionChannel | いいえ |
flush | はい |
cancelled | はい |
race | はい |
delay | はい |
all | 配列またはオブジェクトにブロッキングエフェクトがある場合はブロックします |