javascript - 如果我立即屈服,为什么我的 fork 会阻塞?

标签 javascript asynchronous generator redux-saga

我有一个传奇,它应该查询第三方工具来收集用户界面的状态。由于大量的调用,以及我如何构建调用树,我正在尝试一种用 fork 启动请求的方法,这样我就可以在拼凑所需的调用时并行进行十几个请求,以及加入 fork 调用并收集结果的第二种方法。

我的查询方法应该启动调用,如下所示:

* asyncQuery(action, domain, config) {
   let baseUrl;

   if (config && domain) {
      baseUrl = getBaseUrl(config.deployments, domain);
   }  else {
      baseUrl = yield select(selectUrlForDomain(domain));
   }

   return yield fork(this.doManualGetRequest, action.payload.apiPath, baseUrl);
}


 doManualGetRequest(apiPath, baseUrl) {

     const url = buildUrl(basUrl, apiPath);

     const requestPromise = fetch(url, options)
         .then(checkStatus)
         .then(parseJSON)
         .then((data) => ({ data }))
         .catch((err) => ({ err }));
}

这是由一些逻辑调用的,该逻辑负责构建请求树,并将每个调用添加到队列中。在调用 joinRequets 之前:

* joinRequests(requestsMap) {
    const results = {}
    const requests = Object.entries(requestsMap)


    join(Object.values(requestsMap));

    for (let i = 0; i < requests.length; i++) {

       const [key, request] = request[i];

       results[key] = request.result();
    }

    return results;
}

经过一些实验,我发现每次调用 doManualGetRequest 都会阻塞。具体来说,我可以在我的网络选项卡中观看,因为仅在最后一次调用完成后才进行一次调用,并且我使用了打印语句和 sleep 来确认在 doManualGetRequest 返回的 promise 完成执行之前不会调用新的 fork 。

如果我不在 asyncQuery 中生成 fork 命令,而是在运行 join 命令之前在 joinRequest 中执行生成操作,我会看到所有查询都以正确的异步方式立即发出。

为什么 doManualGetRequest 中的屈服会导致阻塞行为?

最佳答案

yield正在寻找forkdoManualGetRequest阻止因为 doManualGetRequest 在返回之前等待 fork 进程。这里的文档有点棘手,如果你仔细观察,你可以找出原因。

来自文档:

All forked tasks are attached to their parents. When the parent terminates the execution of its own body of instructions, it will wait for all forked tasks to terminate before returning.

https://redux-saga.js.org/docs/api/#forkfn-args

所以,如果 doManualGetRequest 中有更多代码之后yield fork ,该代码将在您 fork 进程后立即运行。然而,doManualGetRequest直到 fork 才会返回已完成(或失败)。

fork的目的这样您就可以附加对异步任务的引用,并可能取消它或检查它是否仍在运行。您的情况,您不需要该功能。 请尝试spawn相反。

从文档中,spawn(fn, ...args):

Same as fork(fn, ...args) but creates a detached task. A detached task remains independent from its parent and acts like a top-level task. The parent will not wait for detached tasks to terminate before returning and all events which may affect the parent or the detached task are completely independents (error, cancellation).

https://redux-saga.js.org/docs/api/#spawnfn-args

关于javascript - 如果我立即屈服,为什么我的 fork 会阻塞?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51878260/

相关文章:

javascript - 如何在 ExtJS 中将停靠项目彼此相邻放置

javascript - 将 HTML 元素的值作为另一个元素的 onclick 调用

php - 多个 ckeditor 具有相同名称的文本区域

javascript - 如何完全禁用 babel transform-regenerator

javascript - 如何从异步调用返回响应?

c++ - 为现有异步代码创建 C++ 阻塞函数

javascript - 将迭代器项分布到子迭代器上

c - 我的消息队列在哪里产生段错误?

javascript - 如何在 JavaScript 中使用异步生成器?

ruby-on-rails - 如何让生成器调用 Rails 3 中的其他生成器