skip to Main Content

I have an asynchronous function in a worker to load image data. This almost always works without any problems. Sometimes a loading process does not seem to work right away and then I no longer get any feedback from the worker. That’s why I want the loading process to be tried a maximum of two more times if it fails. If the file still could not be loaded, I would like to return a default data set so that I can get a feedback in any case

e.g.

data = "not loaded";

return {id, data}

Here is my loading function. I’ve already read something about try and catch, but I still don’t have the necessary understanding of connecting this in connection with a total of three loading attempts and implementing it in my function.

async LoadData(newImages){

   const ids = newImages.map(el => el.id);
   const loader = new THREE.ImageBitmapLoader();   //from three.js library
                
   const sharedImageDatas = await Promise.all(
   ids.map(async (id) => {      
                            
      const url = app_constants.SECOND_IMAGE_LIBRARY + id;          
      let image = await loader.loadAsync(url);
                
      let canvas = new OffscreenCanvas(image.width, image.height); 
      let context = canvas.getContext('2d'); 
      context.drawImage( image, 0, 0 );
                
      let imageData = context.getImageData(0, 0, image.width, image.height);
                        
      const data = new Uint8Array(new SharedArrayBuffer(imageData.data.length));
      data.set(imageData.data, 0);
 
      image = canvas = context = imageData = null;
            
      return {id, data}; 
      })
   );   
        
   return sharedImageDatas;         
}

Can anyone give me any recommendations on how to extend my function to suit what I want?

2

Answers


  1. I rewrote your function – add a check for 3 tries.

    async function LoadData(newImages, maxTries = 3) {
      const ids = newImages.map(el => el.id);
      const loader = new THREE.ImageBitmapLoader(); //from three.js library
      const sharedImageDatas = await Promise.all(ids.map(async (id) => {
        let tries = 0;
        while (tries < maxTries) {
          const url = app_constants.SECOND_IMAGE_LIBRARY + id;
          try {
            let image = await loader.loadAsync(url);
            let canvas = new OffscreenCanvas(image.width, image.height);
            let context = canvas.getContext('2d');
            context.drawImage(image, 0, 0);
            let imageData = context.getImageData(0, 0, image.width, image.height);
            const data = new Uint8Array(new SharedArrayBuffer(imageData.data.length));
            data.set(imageData.data, 0);
            image = canvas = context = imageData = null;
            return { id, data };
          } catch (error) {
            tries++;
          }
        }
        return { id, data: "not loaded" };
      }));
      return sharedImageDatas;
    }
    
    Login or Signup to reply.
  2. Here is an example wrapper function that you should use for map callback.

    async function withRetries(fn) {
      let count = 0;
      const defaultValue = {};
    
      while (count < 3) {
        try {
          const data = await fn();
          return data;
        } catch (error) {
          count++;
        }
      }
    
      return defaultValue;
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search