Почему я не могу использовать это в (JavaScript) Worker при определении объекта? - PullRequest
2 голосов
/ 18 декабря 2011

Исходя из мира Java (OOP), я привык к классам, наследованию и многопоточности.Теперь для моей небольшой прогулки по домену JavaScript, я пытаюсь использовать эти парадигмы и шаблоны, где это применимо.Читайте: используйте прототипы («классы» / объекты) и WebWorkers для параллельного выполнения.Однако этот случай не работает ...

HTML-сайт, запускающий работника:

<html>
    <head>
        <script>
        var worker = new Worker("worker.js");
        worker.onmessage(event) {
            // here be fancy script
        }
        worker.postMessage("run, worker, run!"); 
        </script>
    </head>
    ...
</html>

Работник, вызываемый HTML ("worker.js"):

self.loadScripts("handler.js");
var handler = null;
self.onmessage = function(event) {
    if(!handler) {
        handler = new Handler();
    }

    handler.compute();
}

Обработчик, вызываемый работником ("handler.js"):

function Handler() {
}

Handler.prototype = {
    compute: function() {
        this.doSomething(); // <-- ERROR! "this" points to the worker context,
                            // not to the Handler instance. So "doSomething" is
                            // undefined. However, the following line would work:
        // Handler.prototype.doSomething();
    },
    doSomething: function() {
        // More code here
    }
}

Предназначено ли создание прототипов JavaScript и "наследование" таким образом?Должен ли я всегда использовать свойство prototype вместо этого?Что если я захочу получить доступ к this.myProperty вместо функции?

Также: есть ли разумный способ связать это с экземпляром Handler в конструкторе?По крайней мере, код не загроможден длинными ссылками на прототип Handler.

Спасибо!

1 Ответ

0 голосов
/ 19 декабря 2011

Спасибо за ваши комментарии. Действительно, контекст этого работает как ожидалось. Реальный код использовал обратный вызов времени ожидания:

Handler.prototype = {
    compute: function() {
        self.setTimeout(this.doSomething, 1000); // Here the this got lost
    },
    doSomething: function() {
        // Code here
    }
}

Кажется, это из-за вызова времени ожидания ссылается на рабочий контекст. Чтобы решить эту проблему, я просто обернул обратный вызов в анонимную функцию (ссылаясь на вызывающую функцию как на переменную, как предложил jfriend00):

Handler.prototype = {
    compute: function() {
        var caller = this;
        self.setTimeout(function() { // Wrap for great justice
            caller.doSomething();
            } , 1000);
    }, doSomething: function() {
        // Code here
    }
}

Еще раз спасибо.

...