docs たとえばforkはattached forkで、spawnはdetached fork-どのように違いますか?
それを見る一つの方法は、あなたの物語をグラフとして見ることです。 'fork'は、呼び出しプロセスから子を作成します。 「spawn」はグラフのルートに新しい子を作成します。
したがって、別のプロセスを「フォーク」すると、親プロセスは「フォーク」プロセスが終了するまで待機します。また、すべての例外は子から親にバブルアップし、親でキャッチできます。
ただし、「生成された」プロセスは親をブロックしないため、次の「yield」ステートメントがすぐに呼び出されます。また、親プロセスは、「生成された」プロセスで発生する例外をキャッチできません。
これがお役に立てば幸いです。
同じドキュメントで次のように書かれています:
親が自身の命令本体の実行を終了すると、分岐するすべてのタスクが終了するのを待ってから戻ります。
実行フローの途中でfork
またはspawn
を呼び出すfetchAll()
を呼び出すこのセットアップがあるとします。
_const { delay, runSaga } = require("redux-saga");
const fetch = require("node-fetch");
const { fork, spawn, call, put} = require("redux-saga/effects");
function* fetchResource(resource) {
console.log(`Fetch ${resource} start`);
const response = yield call(fetch, "https://jsonplaceholder.typicode.com" + resource);
const text = yield call(response.text.bind(response));
console.log(`Fetch ${resource} end`);
}
function* fetchAll() {
console.log("Fork or Spawn start");
// this is pseudo code, I mean here that you can use either
// fork or spawn, check results below
const task1 = yield fork||spawn(fetchResource, "/posts/1");
const task2 = yield fork||spawn(fetchResource, "/posts/2");
console.log("Fork or Spawn end");
}
function* main() {
console.log("Main start");
yield call(fetchAll);
console.log("Main end");
}
runSaga({}, main);
// RESULTS WITH FORK(): | RESULTS WITH SPAWN():
// |
// Main start | Main start
// Fork start | Spawn start
// Fetch /posts/1 start | Fetch /posts/1 start
// Fetch /posts/2 start | Fetch /posts/2 start
// Fork end | Spawn end
// Fetch /posts/2 end | Main end <--
// Fetch /posts/1 end | Fetch /posts/2 end
// Main end <-- | Fetch /posts/1 end
_
わかるのは、call
コンテキスト内では、フォークは_non-blocking
_ですが、call
自体がブロッキング効果であるため、call
はすべての子プロセスが終了するまで終了しません。
別のfork
内でfork
を呼び出した場合、fork自体は非ブロッキングであり、内側のフォークされたプロセスは外側のforkプロセスからleak
になりますが、最も近いブロッキングコンテキスト内に保持されるため、同じようには見えません。これが_attachment to parent
_の本質です。
そのため、親yield call(forkedProcess)
は、ブロッキングの性質を持ち、子フォークプロセスのreturn
または_throw resolution
_を待機します。
ただし、spawn()
の場合はそうではありません。スポーンは親プロセスから切り離されているため、つまりルートプロセスにアタッチされているため、ローカルのparent
は待機する必要がありません。
これが少し明確になることを願っています。