我正在用JavaScript执行图像处理操作,该操作按预期工作,有时会冻结UI,这使我不得不使用Web worker来执行图像处理功能。 我有一个需要处理多个的场景。以下是我用于实现上述壮举的工作流的摘要。
//closure
var filter = (function(){
function process(args){
var promise = new Promise(function (resolve, reject) {
if (typeof (Worker) !== "undefined") {
if (typeof (imgWorker) == "undefined") {
imgWorker = new Worker("/processWorker.js");
}
imgWorker.postMessage(args);
imgWorker.onmessage = function (event) {
resolve(event.data);
};
} else {
reject("Sorry, your browser does not support Web Workers...");
}
});
return promise;
}
return {
process: function(args){
return process(args);
}
}
})();
function manipulate(args, callback){
filter.process(args).then(function(res){
callback(res);
});
}
在这里,我正在加载多个图像,并将它们传递到操纵函数中。 在这种情况下,我在这里面临的问题是,有时候对于某些图像,Promise永远不会解决。 在调试我的代码后,我发现这是因为我正在为图像创建Promise,而先前的Promise尚未解决。 我需要有关如何解决此问题的建议,也有另一个查询,我应该多次使用相同的闭包(在上述情况下为此处的过滤器),或者在每次需要时创建新的闭包,如下所示:
var filter = function(){
....
return function(){}
....
}
function manipulate(args, callback){
var abc = filter();
abc.process(args).then(function(res){
callback(res);
});
}
我希望我的问题很清楚,否则请发表评论。
答案 0 :(得分:1)
更好的方法是仅一次加载图像处理Worker
。在您的应用程序启动期间或需要时。
此后,您只能为希望从工作人员调用的功能创建一个Promise。对于您而言,filter
可以在您每次发布到Promise
时返回一个新的Worker
对象。仅当收到来自工作人员针对特定函数调用的答复时,才应解析此Promise对象。
您的代码正在发生的事情是,即使onmessage
处理程序正在处理来自Worker的不同消息,您的诺言也正在解决。即。如果您向员工发布2次。如果第二条帖子返回一条消息,它将自动解析您的两个promise对象。
我在Orc.js处创建了工人封装。尽管由于我尚未清除它内置的某些依赖项,它可能无法立即使用。随意使用我应用的方法。
其他:
您将需要将post
和onmessage
映射到promises
。这也需要您修改Worker代码。
//
let generateID = function(args){
//generate an ID from your args. or find a unique way to distinguish your promises.
return id;
}
let promises = {}
// you can add this object to your filter object if you like. but i placed it here temporarily
//closure
var filter = (function(){
function process(args){
let id = generateID(args)
promises[id] = {}
promises[id].promise = new Promise(function (resolve, reject) {
if (typeof (Worker) !== "undefined") {
if (typeof (imgWorker) == "undefined") {
imgWorker = new Worker("/processWorker.js");
imgWorker.onmessage = function (event) {
let id = generateID(event.data.args) //let your worker return the args so you can check the id of the promise you created.
// resolve only the promise that you need to resolve
promises[id].resolve(event.data);
}
// you dont need to keep assigning a function to the onmessage.
}
imgWorker.postMessage(args);
// you can save all relevant things in your object.
promises[id].resolve = resolve
promises[id].reject = reject
promises[id].args = args
} else {
reject("Sorry, your browser does not support Web Workers...");
}
});
//return the relevant promise
return promises[id].promise;
}
return {
process: function(args){
return process(args);
}
}
})();
function manipulate(args, callback){
filter.process(args).then(function(res){
callback(res);
});
}