0

How do I write a function where everything within the function gets loaded before another function is called? For example, (similar to P5.js) I want to implement a preload function that will load anything that needs to be loaded (ie Images) before executing a setup function.

let someImage;
function preload() {
   someImage = new Image();
   someImage.src = "some URL";
   someImage.onload = imageLoaded;
}
function imageLoaded() {
   //this is called before setup
}
function setup() {
   //I can safely assume everything is properly loaded
}
  • Does this answer your question? [loading an image on web browser using Promise()](https://stackoverflow.com/questions/52059596/loading-an-image-on-web-browser-using-promise) – caramba Mar 16 '21 at 02:51
  • Does this answer your question? [Preloading images with JavaScript](https://stackoverflow.com/questions/3646036/preloading-images-with-javascript) – eamanola Mar 16 '21 at 04:18

4 Answers4

1

To preload an image, you need to actually be careful what order you supply the values. If you add src before onload it is possible that the image will load before the onload function will run.

It is annoyingly more possible than it sounds. Same thing goes for <script> as well.

Here's how I would do it:

let someImage;
function preload() {
  someImage = new Image();
  return new Promise((resolve, reject) => {
    // this will pass the event object in the .then function
    someImage.onload = resolve;

    // Optional if you want to handle images not loading
    // someImage.onerror = reject;

    someImage.src = "some URL";
  });
}

// Now you can do it two ways depending on what floats your boat
// You can change your setup function to be async/await
async function setup() {
  try {
    let imageResult = await preload();
    imageLoaded();
    // code that would be in your original setup function
  } catch (e) {
    // handle error
  }
}

// Or you can do promise chaining with callbacks
preload()
  .then(loadEvent => imageLoaded())
  .then(() => setup());
  // .catch(error => handleError(error)); // Optional;
frankie
  • 201
  • 1
  • 6
0

The best way to implement that in Javascript is to have your preload function return a promise, then put all of your code in the promise success return. If you want functions called in a certain order, then you can do a promise chain.

let someImage;
function preload() {
   someImage = new Image();
   someImage.src = "some URL";
   someImage.onload = imageLoaded;
   return new Promise((resolve)=>resolve());
}
preload().then(function(){
    setup();
});
function setup() {
}

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

https://javascript.info/promise-chaining

Yserbius
  • 1,375
  • 12
  • 18
0

Making sure you assign the Event before the .src, you could execute a function .onload of your image....

function preload(url, doneFunc){
  const img = new Image;
  img.onload = ()=>{
    doneFunc();
  }
  img.onerror = ()=>{
    console.log(img.src+' load failure');
  }
  img.src = url;
}
preload('yourImg.png', ()=>{
  console.log('execute code here');
});

.... or you could use a Promise, like:

function preload(url){
  const img = new Image;
  const p = new Promise((resolve,reject)=>{
    img.onload = ()=>{
      resolve();
    }
    img.onerror = ()=>{
      reject(img.src+' load failure');
    }
  });
  img.src = url;
  return p;
}
preload('not_a_good_src.png').then(()=>{
  console.log('execute code here');
}).catch(error=>{
  console.log(error);
});

Of course, I don't recommend loading the images synchronously, when they can be loaded at the same time instead.

StackSlave
  • 10,613
  • 2
  • 18
  • 35
0

using async await you can do it

let someImage="i-m-a--g-e";
let load = true

function  preload() {
  console.log("running preload",someImage)
   return new Promise((resolve,reject)=>{
     
        if(load){ return resolve()}else{return reject()}
   }
                     );
}

function setup(){ 
console.log("running setup")
}

(async () => {
    await preload();
    setup();
})();

JavaScript Demo: Promise.reject()

nativelectronic
  • 646
  • 4
  • 11