Sunday, June 2, 2024
67
rated 0 times [  74] [ 7]  / answers: 1 / hits: 32394  / 6 Years ago, tue, august 28, 2018, 12:00:00

I'am trying to learn how to make SuperMario in JavaScript from here
Can someone explain flow of the below function 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



I do understand how to use => operator.
Which is used to make length of functions smaller.



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


the above line means that the promise is fulfilled when image is loaded.
So does this mean that the following line is executed and then the event listener is waiting for the image to be downloaded in client browser ?



image.scr = url;


The flow of the below function is a little fuzzy to me



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


EDIT 2:



Okay, this was a stupid post. And yup as the IMAGE from url is loaded in the image object then Event listener fires up the resolve().


More From » html5-canvas

 Answers
4

The code you are showing introduces an asynchronous primitive, Promise, which can be passed around and used to access a resource that hasn't been populated yet.


In this case, you want an Image that is fully loaded and has image data that you can use. However, you can't access the image data until a network request finishes that would fetch the image data.


For example, this won't work:




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




Instead, we have to wait until the loading is done. There are a lot of ways to do that but the most common conventions are to use, callbacks, Promises, or async/await.


The method that you have shown combines callbacks and Promises (out of necessity).


Let's break down the code:




/**
* 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);
});






In all honesty though, the loadImage function could be a little bit more robust since it doesn't handle errors right now. Consider the following enhancement:




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

loadImage(example.com/house.jpg)
.then(img => console.log(`w: ${img.width} | h: ${img.height}`))
.catch(err => console.error(err));




[#53626] Saturday, August 25, 2018, 6 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
zariahdiamondz

Total Points: 649
Total Questions: 109
Total Answers: 88

Location: Tajikistan
Member since Thu, Apr 14, 2022
2 Years ago
;