You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用setTimeout()终止Worker线程报错:Cannot read properties of undefined

为什么直接传递Worker.terminate给setTimeout会报错?

问题场景

在Node.js v18.12.0环境下,尝试用setTimeout直接调用Worker的terminate方法终止线程时触发错误,改用包装函数则能正常运行。

错误信息

node:internal/worker:361
    this[kHandle].stopThread();
                  ^

TypeError: Cannot read properties of undefined (reading 'stopThread')
    at Timeout.terminate [as _onTimeout] (node:internal/worker:361:19)
    at listOnTimeout (node:internal/timers:564:17)
    at process.processTimers (node:internal/timers:507:7)

Node.js v18.12.0

报错代码

const { Worker } = require("node:worker_threads")
const worker = new Worker("./test.js")

const setAppTimeout = (workerName, seconds) => {
    setTimeout(workerName.terminate, seconds * 1000)
}

setAppTimeout(worker, 1)

正常运行的代码

const { Worker } = require("node:worker_threads")
const worker = new Worker("./test.js")

const setAppTimeout = (workerName, seconds) => {
    setTimeout(terminateWorker, seconds * 1000, workerName)
}
const terminateWorker = (workerName) => {
    workerName.terminate()
}

setAppTimeout(worker, 1)

差异原因

核心问题是JavaScript的this绑定规则:

  • 当你直接把workerName.terminate作为参数传给setTimeout时,这个函数会被单独提取出来执行,此时它的this不再指向原Worker实例,而是变成了Timeout对象(或全局对象,取决于执行环境)。terminate方法内部需要通过this访问Worker的内部句柄kHandle,this指向错误就会导致无法读取kHandle,进而抛出错误。
  • 用包装函数terminateWorker时,我们通过workerName.terminate()的形式调用,此时terminate方法的this会隐式绑定到workerName这个Worker实例上,能正确访问内部的kHandle,所以可以正常终止线程。

另外还有两种等价的写法可以解决这个问题:

  • 用箭头函数绑定this:
    setTimeout(() => workerName.terminate(), seconds * 1000)
    
  • 用bind手动绑定this:
    setTimeout(workerName.terminate.bind(workerName), seconds * 1000)
    

内容的提问来源于stack exchange,提问作者NoNameIdeas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 01:15:31