2

Below are my three functions. I am calling function 1 & 2 in 3 but I am getting an error. My text is not showing inside my canvas. Only the image is getting displayed. How can I make the functions delay the text function until make_base finishes loading.

Function 1

function make_base(img) {
    base_image = new Image();
    base_image.src = img;
    base_image.onload = function(){
        context.drawImage(base_image, 0, 0);
    }

}

Function 2

function text(text) {
    context.fillText(text, 50, 50)
}

Function 3

function render() {
    make_base(xxx)
    text(xxx)
}

I have used setTimeout doesnt work because sometimes make_base takes little time to load.

daedsidog
  • 1,732
  • 2
  • 17
  • 36
Mayank
  • 73
  • 2
  • 2
  • 9
  • 1
    so use a promise so you know when it is done. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – epascarello Dec 11 '18 at 19:43

3 Answers3

4

Well since it is an asynchronous task, you need to add logic to tell the next code when to run. Classic way is to use a a callback method:

function make_base(img, callback) {
  base_image = new Image();
  base_image.src = img;
  base_image.onload = function(){
    context.drawImage(base_image, 0, 0);
    callback()
  }
}

function text(text) {
  context.fillText(text, 50, 50)
}

function render() {
  make_base(xxx, function () {
    text(xxx)
  })
}

or move into modern patterns is to use a promise

function make_base(img) {
  return new Promise(function(resolve, reject) {
    base_image = new Image();
    base_image.src = img;
    base_image.onload = function(){
      context.drawImage(base_image, 0, 0);
      resolve()
    }
}

function text(text) {
  context.fillText(text, 50, 50)
}

function render() {
  make_base(xxx).then(function () {
    text(xxx)
  })
}
epascarello
  • 204,599
  • 20
  • 195
  • 236
1

Just call your text() function inside of make_base() onload function so the text() function loads after the make_base() function has finished loading all of its variable declarations like this:

function text(text) {
    context.fillText(text, 50, 50)
}

function make_base(img) {
    base_image = new Image();
    base_image.src = 'https://davidwalsh.name/demo/ringo-ftw.jpg';
    base_image.onload = function(){
        context.drawImage(base_image, 0, 0);
        text(text);
    }
}

function render() {
    make_base(img);
}
AndrewL64
  • 15,794
  • 8
  • 47
  • 79
0

make_base is performing an asynchronous operation and adding a callback for when that operation completes:

base_image.onload = function(){
    context.drawImage(base_image, 0, 0);
}

If you want your text function to be called after that callback, put it in the callback function:

function make_base(img) {
    base_image = new Image();
    base_image.src = img;
    base_image.onload = function(){
        context.drawImage(base_image, 0, 0);
        text();
    }
}

//...

function render() {
    make_base(xxx);
}
David
  • 208,112
  • 36
  • 198
  • 279