Доступ к объекту на прототипе другого объекта из асинхронного вызова - PullRequest
1 голос
/ 16 марта 2011

У меня есть асинхронный вызов, по завершении которого я хочу установить свойство для родителя.

Возьмите следующий класс, cat:

var cat = function(){
   this.isLoaded = false;
   this.image = new Image();
   this.image.onload = function(){
     //how can I set the isLoaded variable above from here??
   }
   this.image.src = "...";
}

Я хочу бытьспособен сделать:

var myCat = new cat();
if(myCat.isLoaded)
....

Я не могу понять, как установить свойство isLoaded выше изнутри загрузки.Я могу получить к нему доступ, просто выполнив команду «isLoaded», но мне кажется, что я обращаюсь к нему по значению, а не по ссылке, и, следовательно, не могу изменить его.

Это кажется простым решением, думаю, мне не хватает более глубокого понимания.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 16 марта 2011

Внутри обратного вызова onload, isLoaded равно undefined, и если вы установите его, оно будет window.isLoaded (по сути, глобальным).

Обратный вызов this также указывает на элемент img, а не на его родительскую функцию. Я сделал переменную that, которая указывает на внешнюю функцию this. Функции в функциях имеют доступ к области видимости своей внешней функции в JavaScript.

var Cat = function(){
   this.isLoaded = false;
   this.image = new Image();
   var that = this;
   this.image.onload = function(){
     that.isLoaded = true;
   }
   this.image.src = "http://www.gravatar.com/avatar/5e28492984e3056904e295c43337655f?s=32&d=identicon&r=PG";
}

var c = new Cat();

console.log(c.isLoaded); // false

setTimeout(function() { console.log(c.isLoaded) }, 1500); // true

jsFiddle .

Конечно, setTimeout() используется только для этого примера. Если вы загружаете изображение, вы должны полагаться на обратные вызовы, потому что единственный другой способ определить, загружено ли изображение, - это опрос - не очень хороший интерфейс.

Вы должны предоставить место для обратного вызова, чтобы вы могли сделать ...

var c = new Cat(function() {
   // Image loaded, proceed.
});
1 голос
/ 16 марта 2011

Как @alex сказал, что вам нужно сослаться на объект cat.

Но если у вас плохое интернет-соединение, setTimeout вам не сильно поможет. Вот пример использования функции обратного вызова вместо setTimeout

var cat = function (callback) {
   var this_cat = this;
   this.isLoaded = false;
   this.image = new Image();
   this.image.onload = function(){
     //how can I set the isLoaded variable above from here??
    this_cat.isLoaded = true;
    if (callback instanceof Function) { //@alex tip: callback instanceof Function is more accurate. Chrome reports the regex literal is a function.
        callback();
    }
   }
   this.image.src = "/images/stand_logo.png";
}

var myCat = new cat(function () {
    console.log('cat loaded');
});
...