Понимание обратного вызова JavaScript с помощью addEventListener - PullRequest
1 голос
/ 19 октября 2011

У меня есть литерал объекта, возвращаемый функцией, и, в свою очередь, этот объект создает iframe и делает несколько вещей, когда DOM загружается в этот iframe. Я хочу иметь возможность "получить" значение, возвращаемое обратным вызовом, когда событие инициируется. Вот упрощенный объект:

var myFunc = function (url) {
  return {
      url: url,
      myMethod: function () {

          // some code here to create my iframe.

          var callbackFunc = function (event) {
             // do some stuff with the dom.
             return aValueAsynchronously;
          };

          var async = my_iframe.addEventListener("DOMContentLoaded", callbackFunc, true);
          my_iframe.src = this.url;
      }      
  }
}

После прочтения этого кода я использую его следующим образом:

var myValue = myFunc.myMethod('http://www.example.org');

и когда example.org завершает загрузку в iFrame, вызывается обратный вызов DOMContentLoaded и возвращается значение (после некоторой логики). Как я могу получить это значение, которое будет присвоено myValue (строка выше)? Я понимаю, что для этого нужно использовать обратный вызов, но где и как?

Большое спасибо за вашу помощь!

Ответы [ 2 ]

0 голосов
/ 19 октября 2011

Если myValue находится в области действия для callBack , просто назначьте его. Если он не находится в области видимости, то к нему нужно обращаться как к свойству некоторого объекта, а ссылка на этот объект должна быть в области видимости для callBack .

В простом случае, если myValue является глобальным и вы ожидаете запуска кода в браузере, тогда callBack может установить window.myValue = ...;. В противном случае callBack необходимо получить к нему доступ как свойство глобального объекта (что эквивалентно window в браузере).

Так что в вашей функции вы можете иметь:

      var callbackFunc = function (event) {
         // do some stuff with the dom.

         window.myValue = aValueAsynchronously;

         return aValueAsynchronously;
      };

Или я полностью упустил суть?

0 голосов
/ 19 октября 2011

Во-первых, указанный вами код не может быть вызван myFunc.myMethod, так как значение функции не имеет свойства myMethod. Вместо этого функция возвращает объект с этим свойством. Поэтому для начала вам необходимо:

var myValue = myFunc('http://foo.com').myMethod();

Однако это только вызовет метод, который устанавливает обратный вызов. Чтобы действительно иметь доступ к aValueAsynchronously, вы можете создать замыкание вокруг этого значения:

var myFunc = function(url){
  var aValueAsynchronously;
  return {
    val : aValueAsynchronously,
    myMethod: function(){
      var callback = function(evt){
        aValueAsynchronously = ...;
      };
      ...register your callback...
    }
  };
};

var obj = myFunc('http://foo.com');
obj.myMethod();
...some time passes, and eventually the callback occurs...
console.log( obj.val ); // This will be what was set in your callback

Вместо этого я лично написал бы код, чтобы я мог передать свой собственный обратный вызов для выполнения из обратного вызова iframe и просто передать специальное значение моему обратному вызову напрямую. (Это звучит странно; см. Код ниже.) Таким образом, вам не нужно ждать, пока значение станет доступным, скорее вы получите уведомление, когда оно будет:

var myFunc = function(url,whenDone){
  return {
    myMethod: function(){
      var callback = function(evt){
        var aValueAsynchronously = ...;
        whenDone(aValueAsynchronously);
      };
      ...register your callback...
    }
  };
};

var myObj = myFunc('http://foo.com',function(specialValue){
  // use specialValue here
});
myObj.myMethod(); // Go
...