загрузка изображения в веб-браузер с помощью Promise () - PullRequest
0 голосов
/ 28 августа 2018

Я пытаюсь узнать, как сделать SuperMario на JavaScript из здесь Может кто-нибудь объяснить поток нижеприведенной функции LoadImage?

function loadImage(url) {
        return new  Promise(resolve => {
            const image = new Image();
            image.addEventListener('load', () => {
                resolve(image);
            });
            image.src = url; 
        });
}

const canvas = document.getElementById('screen');
const context = canvas.getContext('2d');

context.fillRect(0,0,50,50);

loadImage('/img/tiles.png')
.then(image=>{
    context.drawImage(image,0,0);  // the function LoadImage returns a Promise with image object(which is  a constant)
// as parameter and if the promise is fulfilled then the image is drawn. 
/
});

EDIT

Я понимаю, как использовать оператор =>. Который используется для уменьшения длины функций.

image.addEventListener('load', () => {
                resolve(image);

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

image.scr = url;

Поток функции ниже немного неясен для меня

function loadImage(url) {
        return new  Promise(resolve => {
            const image = new Image();
            image.addEventListener('load', () => {
                resolve(image);
            });
            image.src = url; 
        });

РЕДАКТИРОВАТЬ 2:

Хорошо, это был глупый пост. И да, поскольку ИЗОБРАЖЕНИЕ из URL-адреса загружается в объект изображения, тогда прослушиватель событий запускает функцию resol ().

1 Ответ

0 голосов
/ 28 августа 2018

Код, который вы показываете, представляет асинхронный примитив Promise, который можно передавать и использовать для доступа к ресурсу, который еще не заполнен.

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

Например, это не будет работать:

const img = new Image();
img.src = "example.com/house.jpg";
ctx.drawImage(img, 0, 0); // img isn't done loading yet

Вместо этого мы должны дождаться , пока загрузка не будет завершена. Есть много способов сделать это, но наиболее распространенными соглашениями являются использование, обратные вызовы, обещания или async / await.

Показанный вами метод объединяет обратные вызовы и обещания (по необходимости).

Давайте разберем код:

/**
 * Load an image from a given URL
 * @param {String} url The URL of the image resource
 * @returns {Promise<Image>} The loaded image
 */
function loadImage(url) {
  /*
   * We are going to return a Promise which, when we .then
   * will give us an Image that should be fully loaded
   */
  return new Promise(resolve => {
    /*
     * Create the image that we are going to use to
     * to hold the resource
     */
    const image = new Image();
    /*
     * The Image API deals in even listeners and callbacks
     * we attach a listener for the "load" event which fires
     * when the Image has finished the network request and
     * populated the Image with data
     */
    image.addEventListener('load', () => {
      /*
       * You have to manually tell the Promise that you are
       * done dealing with asynchronous stuff and you are ready
       * for it to give anything that attached a callback
       * through .then a realized value.  We do that by calling
       * resolve and passing it the realized value
       */
      resolve(image);
    });
    /*
     * Setting the Image.src is what starts the networking process
     * to populate an image.  After you set it, the browser fires
     * a request to get the resource.  We attached a load listener
     * which will be called once the request finishes and we have
     * image data
     */
    image.src = url;
  });
}

/*
 * To use this we call the loadImage function and call .then
 * on the Promise that it returns, passing a function that we
 * want to receive the realized Image
 */
loadImage("example.com/house.jpg").then(houseImage => {
  ctx.drawImage(houseImage, 0, 0);
});

Честно говоря, функция loadImage может быть немного более надежной, поскольку она не обрабатывает ошибки прямо сейчас. Рассмотрим следующее улучшение:

function loadImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener("load", () => resolve(img));
    img.addEventListener("error", err => reject(err));
    img.src = src;
  });
};

loadImage("example.com/house.jpg")
  .then(img => console.log(`w: ${img.width} | h: ${img.height}`))
  .catch(err => console.error(err));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...