How can I access results from a JavaScript callback function?

I’m having trouble with JavaScript callbacks in my Reveal.js presentation for satellite images. The images update every 15 minutes, but sometimes the latest image isn’t available, so I need to display the previous one instead.

I implemented a function to check if an image exists:

function verifyImage(url, cb) {
  const image = new Image();
  image.onload = () => cb(url, true);
  image.onerror = () => cb(url, false);
  image.src = url;
}

function processResult(url, exists) {
  return exists;
}

const imgUrl = `https://example.com/satellite_${date}_${time}.jpg`;
verifyImage(imgUrl, processResult);

if (imageAvailable) {
  // Show current image
} else {
  // Show previous image
}

How can I properly retrieve and use the callback result in my if-else statement? I’m new to JavaScript and async programming, so any guidance or resource recommendations would be very helpful. Thanks!

I understand your frustration with asynchronous callbacks. One approach you might consider is using async/await, which can make your code more readable and easier to reason about. Here’s how you could modify your code:

async function verifyImage(url) {
  return new Promise((resolve) => {
    const image = new Image();
    image.onload = () => resolve(true);
    image.onerror = () => resolve(false);
    image.src = url;
  });
}

async function updateImage() {
  const imgUrl = `https://example.com/satellite_${date}_${time}.jpg`;
  const imageAvailable = await verifyImage(imgUrl);

  if (imageAvailable) {
    // Show current image
  } else {
    // Show previous image
  }
}

updateImage();

This approach allows you to write synchronous-looking code that handles asynchronous operations. It’s particularly useful for scenarios like yours where you need to wait for a result before proceeding.

I’ve faced similar challenges with image loading in JavaScript. One approach that’s worked well for me is using the Fetch API combined with a timeout. This method can be more reliable, especially when dealing with potentially slow-loading images:

async function verifyImage(url, timeout = 5000) {
  try {
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), timeout);
    
    const response = await fetch(url, { method: 'HEAD', signal: controller.signal });
    clearTimeout(timeoutId);
    
    return response.ok;
  } catch (error) {
    return false;
  }
}

async function updateSatelliteImage() {
  const imgUrl = `https://example.com/satellite_${date}_${time}.jpg`;
  const imageAvailable = await verifyImage(imgUrl);

  if (imageAvailable) {
    document.getElementById('satelliteImg').src = imgUrl;
  } else {
    // Logic to show previous image
  }
}

This approach has the added benefit of allowing you to set a timeout, which can be crucial for maintaining good user experience in presentations. It’s been quite reliable in my projects, especially when dealing with external image sources.

hey there! i’ve dealt with similar issues before. the problem is that your callback is asynchronous, so the if-else runs before the result is available. you could use a Promise instead:

function verifyImage(url) {
  return new Promise((resolve) => {
    const image = new Image();
    image.onload = () => resolve(true);
    image.onerror = () => resolve(false);
    image.src = url;
  });
}

then use it like this:

verifyImage(imgUrl).then(imageAvailable => {
  if (imageAvailable) {
    // Show current image
  } else {
    // Show previous image
  }
});

hope this helps!