-3

I wrote the following code to resize an image:

Main().then(function(x) {
  console.log(x)
});

Main=function() {
  Base64()
    .then(function(i) {
      ImageObject(i)
    })
    .then(function(i) {
      x = Resize(i);
      NOW RETURN 'x'
      AS A PROMISE
    }) //***
});
}

function Base64(i) { //Generate base64 of the image
  let reader = new FileReader();
  reader.readAsDataURL(imaginary.file());
  return new Promise((resolve, reject) => {
    reader.onload = () => {
      resolve(reader.result)
    }
  });
}

function ImageObject(i) { //Load the image
  let img = new Image(0, 0);
  img.src = i;
  return new Promise((resolve, reject) => {
    img.onload = () => {
      resolve(img)
    }
  });
}

function Resize(i) { //Resize image and return base64
  let canvas = document.createElement('canvas');
  let canvasContext = canvas.getContext('2d');
  canvas.width = 300;
  canvas.height = 200;
  canvasContext.drawImage(i, 0, 0, canvas.width, canvas.height);
  return canvas.toDataURL(); //Return the resized base64
}

In the line with the ***, I need to return x as a promise to allow Main to be 'thenable'.

6
  • What do you mean "return x as a promise"?! You can create a promise of (i.e. resolving to x) with Promise.resolve(x), but why would you? You already have a promise chain, whatever you return from the then callback is what it'll resolve to. Commented May 28 at 21:17
  • Jon, I tried that, but Main does not wait for the last then to return. It returns on the first 'then'. Could you provide a full working answer? Thanks. Commented May 28 at 22:43
  • This isn't a code-writing service, and your question doesn't add usefully to the library (looks like you've never taken the tour; it's not too late). See e.g. developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/… Commented May 29 at 7:07
  • @Cymro: It looks like you kept trying random combinations of syntax without validating any single step along the way. Start smaller. It'll also be much simpler if you can make use of async and await (is there any reason you can't?), as that will help with the problem you're having of nesting vs. chaining callbacks. Can you successfully have Main call one asynchronous operation and successfully return a Promise? Once that works then move on to calling a second asynchronous operation, and so on. Commented May 29 at 10:44
  • @Cymro: For example, if you can use await syntax then a single asynchronous operation in Main might look like: const Main = async () => { await Base64(); }; Without await syntax it might be: const Main = () => Base64(); or: const Main = () => { return Base64(); }; Or if you can't use arrow functions for some reason?: function Main() { return Base64(); } There are a variety of ways to structure it, and any way will involve Main either awaiting or returning the Promise of any function it calls. Commented May 29 at 10:55

1 Answer 1

1

then() always returns Promise. you should just add return from your Main and inside last then()

Main().then(function(x) {
  console.log(x)
});
// If you call it before definition, it must be var, or just a normal function
//    Main = function() {
// var Main=function() {
function Main(){
  return Base64()
    .then(function(i) { return ImageObject(i) })
    .then(function(i) { return Resize(i) })

}

function Base64(i) { //Generate base64 of the image
  let reader = new FileReader();
  reader.readAsDataURL(imaginary.file());
  return new Promise((resolve, reject) => {
    reader.onload = () => {
      resolve(reader.result)
    }
  });
}

function ImageObject(i) { //Load the image
  let img = new Image(0, 0);
  img.src = i;
  return new Promise((resolve, reject) => {
    img.onload = () => {
      resolve(img)
    }
  });
}

function Resize(i) { //Resize image and return base64
  let canvas = document.createElement('canvas');
  let canvasContext = canvas.getContext('2d');
  canvas.width = 300;
  canvas.height = 200;
  canvasContext.drawImage(i, 0, 0, canvas.width, canvas.height);
  return canvas.toDataURL(); //Return the resized base64
}

Sign up to request clarification or add additional context in comments.

9 Comments

Solt, are you sure about this? When I tried your suggestion, 'Main' is not waiting for the then chain to finish to return x. It is returning undefined at the first 'then'.
Unfortunately I cannot check with your image loader. Try to return Promise from Resize function also, or make it async - it will do it by itself. You should also put some logs inside every call to see all the stages
Main is not returning undefined, it IS undefined. You need to move the definition of main up to before you try to call it. I suspect that you also need to declare Main, as in const Main = function() {
@Ray Wallace oops!! You are right!
@Cymro That appears to be the same code that this answer provided, just using arrow functions instead of function expressions.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.