gpt4 book ai didi

javascript - Webworker回调后返回结果

转载 作者:行者123 更新时间:2023-11-30 16:29:43 25 4
gpt4 key购买 nike

我有一个 Angular 服务,我将 $q 服务与网络 worker 结合使用。在我使用 webworkers 之前的原始函数中,我的 completeClass 函数将返回一个对象。

我替换了代码以将消息发布到我的新网络 worker 脚本。Webworker 的回调在我添加事件监听器的 initWorkers 函数中。

我的目标是 completeClass 函数返回 webworker 的结果。我怎样才能做到这一点?

this.classWorker = new Worker('app/shared/autocomplete/autocomplete-class-worker.js');

this.completeClass = function(text){
var self = this;
var defer = $q.defer();
classWorker.postMessage([text, this.oldText, this.oldProposals, this.aliases, this.entityClasses])
};

this.initWorkers = function(){
var self = this;
worker.addEventListener('message', function(e) {
defer.resolve(e.data);
self.oldProposals = e.data[1];
self.oldText = text;
return e.data[0];
}, false);
};

最佳答案

如果您要在上一个调用仍在运行时调用工作人员,那么您需要一些东西来排队或跟踪正在进行的请求。我怀疑除非您需要控制请求队列,否则 UI 线程向工作人员发出请求会更简单,因此浏览器实质上会为您排队请求。

但是您仍然需要跟踪以某种方式发送的请求,因此当您从工作人员那里收到一条消息时,您知道它正在响应哪个请求。您可以通过在主线程中执行此操作

  • 为每个请求生成一个唯一的 ID。对于很多情况,一个不断增加的整数就足够了。
  • 创建延迟对象并存储它,并与 ID 相关联
  • 向工作人员发出请求,传递 ID
  • 将延迟对象的 promise 传递回调用者

然后是 worker

  • 收到消息,带ID
  • 做它的工作
  • 将结果连同 ID 一起发回

然后是主线程

  • 接收带有 ID 和工作结果的消息。
  • 通过 ID 检索延迟对象,并使用工作结果对其进行解析。

为此,您可以使用如下代码。我通过仅将 text 传递给工作人员并返回 completeText 来稍微简化您的案例。在真实案例中,您可以添加更多信息。

app.service('AutoComplete', function($q) {
var id = 0;
var worker = new Worker('app/shared/autocomplete/autocomplete-class-worker.js');
var inProgress = {};

this.completeClass = function(text) {
var deferred = $q.defer();
id++;
var request = {
id: id,
text: text
};
inProgress[id] = deferred;
worker.postMessage(request);
return deferred.promise;
};

worker.onmessage = function(e) {
var response = e.data;
var id = response.id;
var type = response.type; // resolve, reject, or notify
var completeText = response.completeText;
inProgress[id][type](completeText);
if (type === 'resolve' || type === 'reject') {
delete inProgress[id];
}
};
});

然后在 worker 中你可以有这样的代码:

self.onmessage = function(e) {
var request = e.data;
var text = request.text;
var id = request.id;

// Do the work here
var completeText = ...

var response = {
id: id,
type: 'resolve', // Can reject the promise in the main thread if desired
completeText: completeText
};

self.postMessage(response);
};

My goal is that the completeClass function returns the result of the webworker. How can I make this happen?

澄清一下,它不能直接返回结果,因为结果是异步计算的,所有的函数调用都必须同步返回。但是它可以返回一个稍后解析为结果的 promise ,就像 $http 所做的那样。要使用上面的内容,你可以做类似的事情

app.controller('MyController', function($scope, AutoComplete) {
$scope.complete = function(text) {
AutoComplete.completeClass(text).then(function(result) {
// Do something with result
});
});
});

注意:从技术上讲,如果 worker 对一个请求同步完成所有工作,则没有必要将 ID 与每个请求一起传递,因此按收到的顺序响应每个调用。在上面的示例中,主线程始终可以假定对工作线程的调用构成一个先进先出队列。但是,传递 ID 可以让工作人员灵活地不按收到的订单完成工作。比如说在以后的版本中它需要做一些异步的事情,比如调用另一个 worker,或者发出一个 ajax 请求,这个方法将允许这样做。

关于javascript - Webworker回调后返回结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33523613/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com