Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何围绕Web Workers API编写承诺包装器?_Javascript_Asynchronous_Es6 Promise_Web Worker - Fatal编程技术网

Javascript 如何围绕Web Workers API编写承诺包装器?

Javascript 如何围绕Web Workers API编写承诺包装器?,javascript,asynchronous,es6-promise,web-worker,Javascript,Asynchronous,Es6 Promise,Web Worker,我正在写一个利用网络工作者的图书馆。该库的消费者不应该看到任何Web Worker内容,而是应该从该库的公共方法中获得如下承诺: // consumer.js const api = new Api(); api.doCalculation(input1).then(data => console.log(data)); api.doCalculation(input2).then(data => console.log(data)); api.doCalculation(inp

我正在写一个利用网络工作者的图书馆。该库的消费者不应该看到任何Web Worker内容,而是应该从该库的公共方法中获得如下承诺:

// consumer.js

const api = new Api();

api.doCalculation(input1).then(data => console.log(data));
api.doCalculation(input2).then(data => console.log(data));
api.doCalculation(input3).then(data => console.log(data));
在我的库代码中,有一个类包装了Web工作者逻辑。在构造函数中,我创建工作线程并设置“消息”事件侦听器,侦听来自工作线程的传入数据。 在这个类中还有一个
doccalculation(input)
方法,它对库的消费者是公开的。它接受输入并将其发送到工作线程以执行实际计算

// api.js

class Api {
  constructor() {
    this.worker = new Worker('worker.js');

    this.worker.addEventListener('message', (e) => {

      // I want to return this e.data from the doCalculation method
      console.log(e.data);
    });
  }

  doCalculation(input) {
    this.worker.postMessage({input: input});

    // I want to return a Promise from this method,
    // holding the result e.data
  }
}
我现在的问题是,如何从持有
e.data
doccalculation
方法返回承诺

我的第一个意图是这样的,这显然不起作用,因为每次调用
doccalculation
都会创建一个新的“消息”事件侦听器

// api.js

class Api {
  constructor() {
    this.worker = new Worker('worker.js');
  }

  doCalculation(input) {
    this.worker.postMessage({input: input});
    return new Promise((resolve => {
      this.worker.addEventListener('message', (e) => {
        resolve(e.data);
      });
    }))
  }
}
这里所有的代码示例都进行了简化,以明确我的观点


我将非常感谢任何关于正确方向的提示

当然,您可以将
resolve
存储在某个地方,例如在对象中:

 this.resolvers = {};
 this.count = 0; // used later to generate unique ids
然后,对于发送给webworker的每个任务,创建一个唯一的id,并将承诺解析器存储在那里

 const id = this.count++;
 // Send id and task to WebWorker
 return new Promise(resolve => this.resolvers[id] = resolve);
然后,当webworker发送消息时,从中获取id,并解析存储的承诺:

 this.resolvers[ id ](data);
 delete this.resolvers[id]; // Prevent memory leak

这样一来,(1)您只需要注册一个处理程序,(2)webworker可以同时处理多个任务,(3)您可以通过检查
Object.keys(this.resolvers)

来轻松确定哪些任务正在webworker上运行!非常干净,它的工作非常完美!