Как установить переменную объекта из асинхронного обратного вызова - PullRequest
0 голосов
/ 08 марта 2012

Я только начал с создания пользовательских объектов в javascript.Я хочу установить this.someObjVar, используя приведенный ниже код, но что-то не так в моем подходе.Возможно, асинхронный ответ использует свою собственную область или поток.

// The code below used like:
someClass = new extfoo.SomeClass();
someClass.loadArrFromFile();
// this will be called far later after async returns
someClass.showSomeObjVar();

extfoo.js
=========
var extfoo = {};

extfoo.SomeClass = function() {
  this.someObjVar = [];
  this.showSomeObjVar = extfoo.showSomeObjVar;
  this.loadArrFromFile = extfoo.loadArrFromFile;
};
// Bad results here
extfoo.showSomeObjVar = function() {
  // results '0'
  console.log('showSomeObjVar: ' + this.someObjVar.length);
};

// Async array population
extfoo.loadArrFromFile = function() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
      this.someObjVar = xhr.responseText.split('\r\n')
      // results '23' elements
      console.log("someObjVar length: "+this.someObjVar.length);
    }
  }
  // request code ...
};

Ответы [ 2 ]

0 голосов
/ 08 марта 2012

Что ж, поскольку это асинхронный запрос, someClass.loadArrFromFile () не будет ожидать завершения запроса, поэтому someClass.showSomeObjVar () будет вызван до его завершения.

Вы можете добавить обработчик завершения для обработки результатов:

extfoo.loadArrFromFile = function(done) {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {
      this.someObjVar = xhr.responseText.split('\r\n')
      // results '23' elements
      console.log("someObjVar length: "+this.someObjVar.length);
      done();
    }
  }

Вы можете сделать что-то вроде этого:

someClass.loadArrFromFile(function() {
  someClass.showSomeObjVar();
});
0 голосов
/ 08 марта 2012

Вы уверены, что this.someObjVar ссылается на extfoo?

Существует вероятность, что объект this в функции extfoo.loadArrFromFile ссылается на саму функцию (xhr.onreadystatechange), а не на объект extfoo:

extfoo.loadArrFromFile = function() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {

      //I'm going to create a new variable for this function called this.someObjVar
      //Cause I don't know about extfoo's.
      this.someObjVar = xhr.responseText.split('\r\n')
      // results '23' elements
      console.log("someObjVar length: "+this.someObjVar.length);

      //Whup, end of the line, I guess I'll just forget about that variable I just made.
    }
  }
  // request code ...
};

Есть несколько способов исправить это, но для проверки попробуйте изменить this в функции extfoo.loadArrFromFile на extfoo.

Вот как это исправить:

extfoo.loadArrFromFile = function() {
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4) {

      //OOOH you mean that object
      extfoo.someObjVar = xhr.responseText.split('\r\n')
      // results '23' elements
      console.log("someObjVar length: "+extfoo.someObjVar.length);

    }
  }
  // request code ...
};

И последнее, что ... 1020 * должно отличаться от extfoo.someObjVar? Этот код будет работать, если это так, но в противном случае вы захотите включить SomeClass между каждой ссылкой.

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