【问题标题】:JS Worker await message before continuingJS Worker 在继续之前等待消息
【发布时间】:2020-12-09 16:45:55
【问题描述】:

我的工人向主脚本发送消息,然后主脚本做出响应。 我想在继续工作之前等待响应,因为响应包含我需要的信息 (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

}

我已经尝试过: 在工作人员中放置一个while循环 while(memoryAvailable

我目前在想我可以使用 async await 和 setTimeout 暂停 x 毫秒,然后在解决承诺时,应该传递消息,但即使我让它工作,它也不是最佳的解决方案。 *我的大脑现在有点炸了,所以也许晚饭后我会尝试这样的。

【问题讨论】:

  • 这是一个 generic solution 用于等待工作任务作为承诺。
  • @ThomasRones 我修改了我的答案,加入了一个循环,等待有足够的可用内存。

标签: javascript worker


【解决方案1】:

所以,我没有对此进行测试,但我认为我会这样处理它:

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 变量,但总的来说这是要走的路
  • @Bergi 啊,真的,我并没有真正考虑更改他的代码,而是添加一个功能以通过承诺返回结果,但你是对的,那个全局变量不是与此格式相关
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2019-01-20
  • 2015-12-22
  • 1970-01-01
相关资源
最近更新 更多