通过 Web Worker 传递 jQuery 引用

Passing jQuery reference through Web Worker

我正在努力将一些 url 轮询请求卸载给网络工作者。为此,我需要从调用的 DOM 元素中获取某些属性,将它们传递到 url 请求中,然后用结果更新原始 DOM 元素。由于多个 DOM 元素使用此函数来获取更新,因此我需要传递 $(this) 或等效的唯一标识符以确保更新正确的元素。

我从 "Passing objects to a web worker" and "Can I pass a jQuery object to a web worker" 等问题中了解到这是不可能的,所以我正在寻找一种方法来模拟它。

这是我的代码的粗略概要:

//main.js
function update(){
    var data = { 'id'     : $(this).attr('itemid'),
                 'filter' : $(this).attr('filter')}
    updatePoller.postMessage(data);
}

//worker.js
this.onmessage = function(e){
    //format params from e.data
    //make GET request to url
    //when done...
    postMessage(req.responseText);
}

//main.js (again)
updatePoller.onmessage = function(message){
    //process response
    //update child elements of $(this)
}

如您所见,我不需要访问 Web Worker 内部的 $(this),但在请求返回后我需要引用以便更新正确的元素。有什么方法可以通过 Web Worker 传递对 DOM 元素的唯一引用吗?

当您不能使用其引用时唯一标识元素的常用方法是使用 id。或者,您可以使用 data-* 属性,但实际上 id 是为此特定目的而制作的。

所以(见评论):

//main.js
var lastId = 0;
function update(){
    // Assign ID if necessary
    if (!this.id) {
        ++lastId;
        this.id = "__auto" + lastId;
    }
    var data = { 'id'       : $(this).attr('itemid'),
                 'filter'   : $(this).attr('filter'),
                 'elementId': this.id}
    updatePoller.postMessage(data);
}

//main.js (again)
updatePoller.onmessage = function(message){
    // Use the `element` value sent back to look it up by ID:
    $("#" + message.data.elementId).xyz();
}

如果让所有这些自动全局变量(因为 id 值创建自动全局变量)困扰您,您可以在完成后删除 ID:

//main.js (again)
updatePoller.onmessage = function(message){
    var elm = $("#" + message.data.elementId);
    if (elm.attr("id").startsWith("__auto")) {  // auto ID?
        elm.attr("id", "");                     // remove it
    }
    elm.xyz();
}

或更少 jQuery:

//main.js (again)
updatePoller.onmessage = function(message){
    var elm = $("#" + message.data.elementId)[0];
    if (elm && elm.id.startsWith("__auto")) {
        elm.id = "";
    }
    $(elm).xyz();
}