Асинхронный JavaScript и постоянство объектов - PullRequest
3 голосов
/ 14 февраля 2011

У меня код JS примерно такой:

function myObject()
{
    this.a = 13;

    this.fetchData = function()
    {
        alert(this.a);
        getData(this.processData);
    }

    this.processData = function(data)
    {
        // do stuff with data
        alert(this.a);
    }

    this.fetchData();
}

function getData(callback)
{
    // do async request for data and call callback with the result
}

Моя проблема в том, что функция fetchData имеет доступ к моей переменной a через это ключевое слово , но другая функция processData не вызывается при getData .Я понимаю, почему это происходит, но не знаю, как обойти это.

Как бы вы подошли к этой проблеме предпочтительно в стиле ООП?(Функция getData должна быть доступна для нескольких классов)

Ответы [ 2 ]

4 голосов
/ 14 февраля 2011

Два варианта:

1) У getData принять параметр контекста (обычно называемый context или thisArg) и использовать callback.apply(context, ...) или callback.call(context, ...) для его вызова.Итак:

function getData(callback, context) {
    // ...when it's time to call it:
    callback.call(context, arg1, arg2);
    // or
    callback.apply(context, [arg1, arg2]);
}

2) Создайте функцию, которая при вызове развернется и вызовет исходный обратный вызов с this, установленным на правильное значение.(Это иногда называют «привязкой».)

Например, используя явное замыкание:

this.fetchData = function()
{
    var self = this;

    alert(this.a);
    getData(getDataCallback);

    function getDataCallback(arg1, arg2) {
        self.processData(arg1, arg2);
    }
}

Или используйте для этого универсальную функцию bind (которая также включаетзамыкание, но в хорошем контролируемом контексте, поэтому оно не закрывает ненужные вещи).См. Ссылку ниже для примера простой функции bind.

Подробнее: Вы должны запомнить this

1 голос
/ 14 февраля 2011

Я думаю, что вам нужно только определить "a" как локальную переменную, чтобы она находилась в зависимости от fetchData и getData, что-то вроде этого:

function myObject() {
   var a = 13;

   this.fetchData = function() {
      alert(a);
      getData(this.processData);
   }

   this.processData = function(data) {
      // do stuff with data
      alert(a);
   }

   this.fetchData();
}

Вы также можете сделать,

function myObject() {
   this.a = 13;
   var that = this;

   this.fetchData = function() {
      alert(that.a);
      getData(this.processData);
   }

   this.processData = function(data) {
      // do stuff with data
      alert(that.a);
   }

   this.fetchData();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...