JS Worker 在继续之前等待消息
JS Worker await message before continuing
我的工人向主脚本发送消息,然后主脚本响应。
我想在继续工作之前等待响应,因为响应包含我需要的信息 (memoryAvailable)。
Main.js
export function convert(){
let managingWorker = new Worker("managingWorker.js");
let fileNode = document.querySelector('.fileInput');
managingWorker.postMessage({fileList:fileNode.files, msgType:"processData", options:{delimiter:
document.querySelector('#specifyDelimiter').value.trim() || ","}});
managingWorker.onmessage = function(e){
switch(e.data.msgType){
case "memoryInfoRequested":
let memAvail = performance.memory.jsHeapSizeLimit - performance.memory.totalJSHeapSize;
managingWorker.postMessage({msgType:"memoryInfoReceived", memoryAvailable: memAvail});
break;
//Other cases for updating the UI
}
managingWorker.js
let memoryAvailable = 0;
onmessage = function(e){
switch(e.data.msgType){
case "processData":
workerStuff(e)
break;
case "memoryInfoReceived":
memoryAvailable = e.data.memoryAvailable
break;
}
}
function workerStuff(f){
//do stuff
postMessage({msgType:"memoryInfoRequested"})
//do more stuff if there is enough memory available, else wait
}
我已经尝试过:
在 worker 中放置一个 while 循环
while(memoryAvailable < 5){//什么都不做}
但随后工作人员陷入 while 循环,永远没有机会收到消息。
我目前在想我可以使用 async await 和 setTimeout 暂停 x 毫秒,然后在 promise 被解决时,消息应该被传递,但即使我让它工作,它也不是最优解。 *我现在脑子有点炸了,所以也许晚饭后我会尝试这样的事情。
所以,我还没有测试过这个,但我认为我会这样处理它:
managingWorker.js
let waitForMemoryResolve = () => {};
onmessage = function(e){
switch(e.data.msgType){
case "processData":
workerStuff(e)
break;
case "memoryInfoReceived":
memoryAvailable = e.data.memoryAvailable;
waitForMemoryResolve(memoryAvailable);
break;
}
}
function workerStuff(f){
//do stuff
let memoryAvailable = await waitForMemory();
while (memoryAvailable < 2000) { // or whatever memory you want
await new Promise(r => setTimeout(r, 500)); // wait a half second and check again
memoryAvailable = await waitForMemory();
}
// once here, we have > 2000 memory, so begin work
}
async function waitForMemory() {
return new Promise((resolve, reject) => {
waitForMemoryResolve = resolve;
postMessage({msgType:"memoryInfoRequested"})
})
}
您可以从其他地方的 promise 内部传递 'resolve' 函数,并允许代码的其他部分解析您的 promise。我会这样使用它。
同样,还没有测试过,但我认为这个想法是合理的
我的工人向主脚本发送消息,然后主脚本响应。 我想在继续工作之前等待响应,因为响应包含我需要的信息 (memoryAvailable)。
Main.js
export function convert(){
let managingWorker = new Worker("managingWorker.js");
let fileNode = document.querySelector('.fileInput');
managingWorker.postMessage({fileList:fileNode.files, msgType:"processData", options:{delimiter:
document.querySelector('#specifyDelimiter').value.trim() || ","}});
managingWorker.onmessage = function(e){
switch(e.data.msgType){
case "memoryInfoRequested":
let memAvail = performance.memory.jsHeapSizeLimit - performance.memory.totalJSHeapSize;
managingWorker.postMessage({msgType:"memoryInfoReceived", memoryAvailable: memAvail});
break;
//Other cases for updating the UI
}
managingWorker.js
let memoryAvailable = 0;
onmessage = function(e){
switch(e.data.msgType){
case "processData":
workerStuff(e)
break;
case "memoryInfoReceived":
memoryAvailable = e.data.memoryAvailable
break;
}
}
function workerStuff(f){
//do stuff
postMessage({msgType:"memoryInfoRequested"})
//do more stuff if there is enough memory available, else wait
}
我已经尝试过: 在 worker 中放置一个 while 循环 while(memoryAvailable < 5){//什么都不做} 但随后工作人员陷入 while 循环,永远没有机会收到消息。
我目前在想我可以使用 async await 和 setTimeout 暂停 x 毫秒,然后在 promise 被解决时,消息应该被传递,但即使我让它工作,它也不是最优解。 *我现在脑子有点炸了,所以也许晚饭后我会尝试这样的事情。
所以,我还没有测试过这个,但我认为我会这样处理它:
managingWorker.js
let waitForMemoryResolve = () => {};
onmessage = function(e){
switch(e.data.msgType){
case "processData":
workerStuff(e)
break;
case "memoryInfoReceived":
memoryAvailable = e.data.memoryAvailable;
waitForMemoryResolve(memoryAvailable);
break;
}
}
function workerStuff(f){
//do stuff
let memoryAvailable = await waitForMemory();
while (memoryAvailable < 2000) { // or whatever memory you want
await new Promise(r => setTimeout(r, 500)); // wait a half second and check again
memoryAvailable = await waitForMemory();
}
// once here, we have > 2000 memory, so begin work
}
async function waitForMemory() {
return new Promise((resolve, reject) => {
waitForMemoryResolve = resolve;
postMessage({msgType:"memoryInfoRequested"})
})
}
您可以从其他地方的 promise 内部传递 'resolve' 函数,并允许代码的其他部分解析您的 promise。我会这样使用它。
同样,还没有测试过,但我认为这个想法是合理的