0

我有一个带有状态变量的 React 组件jobs。当状态变量ready为真时,它应该开始由 Web Worker 执行作业(一次一个)。

import React, { useEffect, useRef } from 'react'


// create webworker
const job_worker = new Worker("worker.bundle.js", { type: "module" });


function App() {

  const [jobs, set_jobs] = React.useState([
    { ... },
    { ... },
  ])
  const [ready, set_ready] = React.useState(false)

  // start worker loop
  useEffect(() => {
    const worker_loop = async () => {
      setTimeout(async () => {
        // check if ready to execute a job
        if (ready) {    // <== suffers from 'stale closure'

          // grab a job
          const job = jobsRef.current.find(j => !j.done)

          // listen for webworker results
          job_worker.onmessage = (e) => {
            console.log("received response from webworker: '", e.data, "'")
            
            // SET RESULT IN JOB

            // job is handled by worker; now start the worker_loop again
            return worker_loop()
          }
          
          // post job to worker
          job_worker.postMessage({job: job})
          return  // do not continue; 'onmessage' will continue the loop
        }

        return worker_loop()
      }, 1000)
    }

    // start worker_loop
    worker_loop()
  }, [])


  return (
    <div>
      {/* code to add jobs and set ready state */}
    </div>
  );
}

我尝试通过使用 (infinite) 来做到这一点worker_loop,它在 React 组件安装时启动(使用 useEffect)。循环有点工作,但ready内部的变量worker_loop保持在初始状态值(称为“陈旧关闭”问题)。jobs状态变量可能相同。

我已经尝试按照此处的建议使用“createRef” 。但问题仍然存在。我也觉得有一个更简单的解决方案。

有没有更好的方法来处理 React 状态变量中的“作业”?某种可以访问 React 组件的“job-runner 进程/功能”。顺便说一句,我没有义务使用 WebWorker。

4

1 回答 1

0

感谢您的评论!

控制 React 之外的工作确实更有意义。我通过使用创建一个全局状态来解决它@hookstate/core。这使得访问和控制 React 之外的状态成为可能。更简洁的代码!

于 2021-08-10T12:00:30.400 回答