Как сделать загрузку изображения синхронной?

Я хочу создать объект, который имеет свойство image, но я хочу, чтобы contstructor закончил работу только после загрузки изображения. Или описать это с помощью кода:

GraphicObject = Class.extend({

    //This is the constructor
    init: function(){
          this.graphic = new Image();
          this.graphic.src = 'path/to/file.png';

          while(true)
          {
              this.graphic.onload = function(){break;};
              //I know this won't work since the 'break' is on a different context
              //but you got what I try to do.
          }
     }


})

для тех, кто не знаком с нотацией класса, которую я использую в своем скрипте, она основана на этой

какие идеи?

4 ответов


это возможно, но только с древнее искусство of в base64 и данные-URL-адрес.

GIF изображение преобразуется в Base64.

руны.b64

R0lGODlhIwAjAIAAAP///wAAACwAAAAAIwAjAAACf4SPqcsb3R40ocpJK7YaA35FnPdZGxg647kyqId2SQzHqdlCdgdmqcvbHXKi4AthYiGPvp9KVuoNocWLMOpUtHaS5CS54mZntiWNRWymn14tU7c2t6ukOJlKR5OiNTzQ7wb41LdnJ1coeNg3pojGqFZniPU4lTi0d4mpucmpUAAAOw==

JavaScript, который загружает преобразованное изображение, формирует тот же сервер через блокировку AJAX.

загрузчика.js

var request = new XMLHttpRequest();
var image = document.createElement('img');

request.open('GET', 'rune.b64', false);
request.send(null);

if (request.status === 200) {
  image.src= 'data:image/gif;base64,' + request.responseText.trim();

  document.getElementsByTagName("body")[0].appendChild(image); 
}

проблемы

  • некоторые старые браузеры не любят (большие) URL-адреса данных
  • кодировка Base64 делает изображения около 37% больше
  • весь пользовательский интерфейс блокируется до загрузки изображения

Это очень-зло путь


поставить зависимый код в callback. нет другой не-зло


var timeOut = 5*1000; //ms - waiting for max 5s to laoad
var start = new Date().getTime();
while(1)
  if(img.complete || img.naturalWidth || new Date().getTime()-start>timeOut)
    break;

на основе этой ответ.


я завернул его в функцию, и это сработало!

for (var i = 0, i < asset.length; i++) {

    var img = new Image();
    img.src = "file:///" + folder + "/" + asset[i].name;

    getWdrp(img);

    function getWdrp (img) {
        img.onload = function(){
            // work with the image file
        }
    }
}

Это пример, который работал для меня, потому что раньше, когда я обрабатывал изображение без обертывания функции, он работал бы асинхронно, теперь это асинхронно.