Javascript 向webworker发布函数

Javascript 向webworker发布函数,javascript,web-worker,Javascript,Web Worker,如何从我的主线程向我的工作线程发送函数(副本) 每当我尝试:worker.postMessage({data,func:(data)=>data),firefox都会给我一条错误消息:DataCloneError:无法克隆对象。 至于Chrome,消息有所不同,但仍然出现错误:未捕获的DomeException:未能在“Worker”上执行“postMessage”:无法克隆对象。尚未对此进行测试,但根据规范,似乎只有可以发送给Worker的对象才是“可转移”对象: 我发现了一些示例,在第一个

如何从我的主线程向我的工作线程发送函数(副本)

每当我尝试:
worker.postMessage({data,func:(data)=>data)
,firefox都会给我一条错误消息:DataCloneError:无法克隆对象。


至于Chrome,消息有所不同,但仍然出现错误:未捕获的DomeException:未能在“Worker”上执行“postMessage”:无法克隆对象。

尚未对此进行测试,但根据规范,似乎只有可以发送给Worker的对象才是“可转移”对象:

我发现了一些示例,在第一个示例中,过程没有详细说明,但我猜他使用了一种类型或URL编码,对于一个对象,它可以像第二个示例中那样转换为JSON


我也必须在几天内完成这项工作,我可以随时更新将要测试的内容。

是的,这是可能的,我做到了,,而且比这更好的是,我可以创建没有js文件的web workers,只需使用javascript代码生成的Blob文件

setInterval(()=>{console.log(“non-bloke”+Math.random())},900)
log(“在Worker中启动阻塞代码”)
控制台时间(“阻塞”)
genericWorker(窗口,[“块CPU”,函数(块){
block(10000)//此blockCpu函数定义如下
return`\n\nbla${123123*2312}bla\n`//这在已解析的承诺中捕获
}]).然后(函数(结果){
控制台。时间结束(“阻止”)
日志(“阻塞代码结束”,结果)
})
.catch(函数(错误){console.log(错误)})
/*如果Web Worker不使用文件,它将从Blob创建该文件
@cb_context,回调函数参数所在的上下文,例如:window
@cb,[“fn_name1”,“fn_name2”,函数(fn1,fn2){}]
将执行回调,您可以将其他函数传递给该cb
*/
函数genericWorker(cb_上下文,cb){
返回新承诺(功能(解决、拒绝){
if(!cb | |!Array.isArray(cb))
返回拒绝(“无效数据”)
var callback=cb.pop()
var函数=cb
if(typeof callback!=“function”| | functions.some((fn)=>{返回cb_上下文的类型[fn]!=“function”}))
return reject(`回调或某些参数:(${functions.toString()})不是函数`)
if(functions.length>0&&!cb_上下文)
返回拒绝(“上下文未定义”)
callback=fn\u string(callback)//要执行的回调
functions=functions.map((fn_name)=>{返回fn_字符串(cb_上下文[fn_name]))
var worker_file=window.URL.createObjectURL(新Blob([“self.addEventListener('message',function(e){var bb={};var args=[];for(fn of e.data.functions){bb[fn.name]=新函数(fn.args,fn.body);args.push(fn.name)};var回调=新函数(e.data.callback.args,e.data.callback.body);args=args.map(函数(fn_name){返回bb[fn_name]};var result=callback.apply(null,args);self.postMessage(result);},false)]
var worker=新的worker(worker\u文件)
postMessage({callback:callback,functions:functions})
worker.addEventListener('error',函数(error){return reject(error.message)})
worker.addEventListener('message',函数(e){
解析(如数据),worker.terminate()
},错)
//从函数到字符串,以及其名称、参数和正文
函数fn_字符串(fn){
var name=fn.name,fn=fn.toString()
返回{name:name,
args:fn.substring(fn.indexOf(“”+1,fn.indexOf(“”)),
正文:fn.substring(fn.indexOf(“{”)+1,fn.lastIndexOf(“}”))
}
}
})
}
//随机阻塞函数
功能块CPU(毫秒){
var now=new Date().getTime();
var结果=0
while(true){
结果+=Math.random()*Math.random();
如果(新日期().getTime()>now+ms)
返回;
}   

}
为了能够发布任何函数(包括匿名函数),我需要先调用它,然后从worker内部调用它。这是否回答了您的问题?您发布了几乎完全相同的消息。但是您的实现不同-您是否将其中一条消息更新为首选实现。此问题应标记为这是重复的。