在 JavaScript 闭包中使用 promise 与 web worker 一起工作
Using promise to work with web worker inside a JavaScript closure
我在 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);
});
}
在这里,我正在加载多个图像并将它们传递到 manipulate 函数中。
在这种情况下,我在这里面临的问题是,有时对于少数图像,Promise 并非永远无法解决。
在调试我的代码后,我发现这是因为我正在为图像创建一个 Promise,而之前的 Promise 没有得到解决。
我需要关于如何解决这个问题的建议,我还有另一个问题,我是否应该多次使用相同的闭包(在上面的场景中使用过滤器),或者每次需要时都创建新的闭包,如下所示:
var filter = function(){
....
return function(){}
....
}
function manipulate(args, callback){
var abc = filter();
abc.process(args).then(function(res){
callback(res);
});
}
我希望我的问题很清楚,如果没有请评论。
更好的方法是只加载图像处理 Worker
一次。在您的应用程序启动期间或需要时。
之后,您可以只为您希望从 worker 调用的函数创建一个 Promise。在你的例子中,每次你 post 到 Worker
时,filter
可以 return 一个新的 Promise
对象。仅当从 worker 收到特定函数调用的回复时,才应解析此 promise 对象。
您的代码发生的情况是,即使 onmessage
处理程序正在处理来自 Worker 的不同消息,您的承诺仍在解决。 IE。如果你 post 2次给工人。如果第二个 post return 是一条消息,它会自动解析您的两个承诺对象。
我这里创建了一个worker封装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);
});
}
我在 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);
});
}
在这里,我正在加载多个图像并将它们传递到 manipulate 函数中。 在这种情况下,我在这里面临的问题是,有时对于少数图像,Promise 并非永远无法解决。 在调试我的代码后,我发现这是因为我正在为图像创建一个 Promise,而之前的 Promise 没有得到解决。 我需要关于如何解决这个问题的建议,我还有另一个问题,我是否应该多次使用相同的闭包(在上面的场景中使用过滤器),或者每次需要时都创建新的闭包,如下所示:
var filter = function(){
....
return function(){}
....
}
function manipulate(args, callback){
var abc = filter();
abc.process(args).then(function(res){
callback(res);
});
}
我希望我的问题很清楚,如果没有请评论。
更好的方法是只加载图像处理 Worker
一次。在您的应用程序启动期间或需要时。
之后,您可以只为您希望从 worker 调用的函数创建一个 Promise。在你的例子中,每次你 post 到 Worker
时,filter
可以 return 一个新的 Promise
对象。仅当从 worker 收到特定函数调用的回复时,才应解析此 promise 对象。
您的代码发生的情况是,即使 onmessage
处理程序正在处理来自 Worker 的不同消息,您的承诺仍在解决。 IE。如果你 post 2次给工人。如果第二个 post return 是一条消息,它会自动解析您的两个承诺对象。
我这里创建了一个worker封装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);
});
}