Как получить переменную, возвращаемую несколькими функциями - Javascript / jQuery - PullRequest
2 голосов
/ 20 августа 2010

Вкратце, этот вопрос состоит в том, чтобы выяснить, как передавать переменные между функциями javascript без: возврата переменных, передачи параметров между основными функциями, использования глобальных переменных и принуждения функции 1 ожидать завершения функции 2. Я разобрался с решением jQuery и написал ниже (в разделе ответов).


Old Post: я инициализирую набор из четырех функций, каждая из которых вызывает друг друга по-своему. В конце мне нужен окончательный модифицированный продукт (массив), возвращенный в функцию инициализации.

Глобальные переменные не заставляют начальную функцию ждать. И вернуть его обратно четыре раза тоже не получится. Как передать измененную переменную обратно в функцию инициализации, если вы не можете ее вернуть? Или почему он не возвращается?

(лабиринт начинается с initFunctionA, заканчивается functionD)

classOne = {
  initFunctionA : function() {
    classTwo.functionB(functionD, array);
    // I NEED ACCESS TO ARRAY2 HERE
  },
  functionD : function(data, array) {
    var array2 = // modifications to array
  }
}

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
}

Ответы [ 5 ]

1 голос
/ 22 августа 2010

Измените свой обратный вызов (на сайте вызовов) так, чтобы вы зафиксировали возвращаемое значение functionD. Затем измените functionD так, чтобы он возвращал array2. Для удобства я добавил this доступ к примеру ниже. (Кроме того, обязательно добавляйте точки с запятой там, где это необходимо, если вы хотите сделать JSLint счастливым.)

classOne = {
  initFunctionA : function() {
    var self = this;

    classTwo.functionB(function() {
        var array2 = functionD.apply(self, arguments);

        // ACCESS ARRAY2 HERE
    }, array);
  },
  functionD : function(data, array) {
    var array2 = // modifications to array

    return array2;
  }
};

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
};
1 голос
/ 20 августа 2010

Я бы использовал конструктор объекта:

function ClassOne() {
    this.array2 = [];
}

ClassOne.prototype.initFunctionA = function() {
    // ...
}

ClassOne.prototype.functionD = function(data, array) {
    // Can use array2 EX: this.array2
}

var classOne = new ClassOne();
1 голос
/ 20 августа 2010

Вы не можете заставить его работать с шаблоном, как вы написали там;это просто невозможно в Javascript, потому что нет такого понятия, как «ожидание».Ваш ajax-код должен принимать параметр обратного вызова (который у вас есть, хотя неясно, откуда он берется и что он делает), и эта начальная функция должна передать код, чтобы сделать то, что вам нужно с массивом после вызова ajaxотделка.

0 голосов
/ 22 августа 2010

Хорошо!Я нашел способ передавать переменные между функциями без:

  • создания глобальных переменных
  • создания свойств объекта (решение Хаоса)
  • передачи параметров

Эти три были предложены здесь как единственные способы.

Доступ к переменным из других функций без использования глобальных переменных

Но, если вы не можете передать параметрынапрямую, и вам нужна одна функция для ожидания другой (то есть, вы не можете полагаться на ссылки), и вы используете асинхронные вызовы сервера в промежуточной функции, тогда ваше единственное решение:

Используя jQuery ...

Создайте этот объект в DOM (динамически, если вы не хотите запутывать свою разметку):

<div id='#domJSHandler" style="display: none;"></div>

Затем в функции, которая должна ждать:

//Function & Class Set 2
$('#domJSHandler').bind('proceedWithAction', function(event, param1, param2) {
    // action set 2
});

А в функции, которую следует ожидать:

//Function & Class Set 1
// action set 1
$('#domJSHandler').triggerHandler('proceedWithAction', [param1, param2]);

По сути, включают в себя последние действия, которые необходимо выполнить в пользовательском событии связывания jQuery с невидимым объектом DOM.Запустите это событие из JS с помощью triggerHandler в jQuery.Передайте свои параметры и вуаля!

Я уверен, что SO даст мне дерьмо для этого (и для самовольного принятия моего собственного ответа), но я думаю, что это довольно блестяще для супер-новичка, и это сработало для меня.

Итак: p Переполнение стека (jk Вы все много раз спасали мою задницу, и я вас всех люблю:)

0 голосов
/ 20 августа 2010

Вот как я понимаю вашу проблему: classTwo обрабатывает вызов AJAX и может изменить результат. classOne использует classTwo для получения некоторых данных и нуждается в результирующих данных.

Если так, как это:

classOne = {
  initFunctionA : function() {
    var array = ['a','b','c'];
    classTwo.functionB(this.functionD, array);
  },
  functionD : function(data, array) {
    // This function is called when the AJAX returns.
    var array2 = // modifications to array
  }
}

{...}

classTwo = {
  functionB : function(callback, array) {
    $.ajax({
      success: function(ret){
        classTwo.functionC(ret, callback, array)
      }
    });
  },
  functionC : function(ret, callback, array) {
     callback(ret.data.x, array);
  }
}

Таким образом, classOne.initFunctionA вызывает classTwo.functionB, который устанавливает вызов ajax. Когда вызов ajax завершается успешно, вызывается classTwo.functionC с результатом и исходным массивом. Отсюда classOne.functionD вызывается с ret.data.x и массивом.

...