redux-saga中fork和spawn的区别是什么?

Pau*_*ulB 28 redux-saga

文档称叉是一个连接叉和产卵是分离叉 - ?有什么不同?

Ale*_*lex 25

查看它的一种方法是将您的传奇视为图形.'fork'从调用进程创建一个子进程.虽然'spawn'在图的根部创建一个新的子项.

因此,当您"分叉"另一个进程时,父进程将一直等到"分叉"进程完成.此外,每个异常都会从子级冒泡到父级,并且可以在父级中捕获.

'衍生'过程虽然不会阻止父进程,所以立即调用下一个'yield'语句.此外,父进程将无法捕获"生成"进程中发生的任何异常.

我希望这可以帮到你.

  • “生成的”进程不会阻止父进程。“ fork”的进程也是如此,不是吗? (2认同)
  • 问题中发布的文档直接与您相矛盾:https://redux-saga.js.org/docs/advanced/ForkModel.html 向下滚动页面到示例。fork 和spawn 都是非阻塞的。对于 fork,父任务将从子任务异步接收异常。 (2认同)

Kar*_*yan 23

它在同一个文档中说:

当父进程终止执行它自己的指令体时,它将等待所有分叉任务在返回之前终止.

假设我们有这样的设置,在执行流程的中间我们调用fetchAll()可以调用fork或者spawn:

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
Run Code Online (Sandbox Code Playgroud)

我们看到的是,在callfork的上下文中non-blocking,但是call在它的所有子进程完成之前不会完成,因为call它本身就是阻塞效果.

如果你fork在另一个内部调用,你就不会看到相同的内容fork,因为fork本身是非阻塞的,而内部分叉进程leak不在外部fork进程中,而是保存在最近的阻塞上下文中.这是本质attachment to parent.

因此yield call(forkedProcess),具有阻塞性质的父级将等待子级进程returnthrow resolution子进程.

spawn()但是,情况并非如此,因为spawn与封闭的父进程分离,即附加到根进程,因此本地parent不必等待.

希望这能澄清一下.