skip to Main Content

For the below posted code, I collect the Promises in both of the arrayspromisesTS1 and promisesTS2. I want the collected promises to be executed later when i call or execute something like the following:

individualBandsDataForPathForTS1.map(async data => {
    data.map(load => {
        load.map(composition => {
            switch(composition.band) {
                case SysConstants.CONST_BAND_1_RAW_NAME_IS_AVERAGES.description:
                    promisesTS1.push(new Promise((resolve, reject) => {
                        // ts1Compositions[0] = composition;
                        sorted = composition.contents.sort((a, b) => a-b);
                        thresholdsInfoForBand1ForTS1 = {
                            band1_minMaxNDVI_TS1: MathUtils.findMinMax('band_1_ndvis_averages_MinMaxGeoTIFF_TS1_', composition.contents),
                            band1_percentile10_TS1: MathUtils.findPercentile('band_1_ndvis_averages_P10_GeoTIFF_TS1_', sorted, .1).percentile,
                            band1_percentile90_TS1: MathUtils.findPercentile('band_1_ndvis_averages_P90_GeoTIFF_TS1_', sorted, .9).percentile,
                        };
                        resolve({
                            compositionsOfBand1ForTS1: composition,
                            sorted: sorted,
                            thresholdsInfoForBand1ForTS1,  
                        });
                    }).then(() => {
                        compositionsOfTS1.push(composition);
                    })
                    );
                    break;
                case SysConstants.CONST_BAND_2_RAW_NAME_IS_NUM_OF_CLOUD_FREE_SAMPLES.description:
                    promisesTS1.push(new Promise((resolve, reject) => {
                        // ts1Compositions[1] = composition;
                        sorted = composition.contents.sort((a, b) => a-b);
                        thresholdsInfoForBand2ForTS1 = {
                            band2_minMaxNDVI_TS1: MathUtils.findMinMax('band_2_num_of_cloud_free_samples_MinMaxGeoTIFF_TS1_', composition.contents),
                            band2_percentile10_TS1: MathUtils.findPercentile('band_2_num_of_cloud_free_samples_P10_GeoTIFF_TS1_', sorted, .1).percentile,
                            band2_percentile90_TS1: MathUtils.findPercentile('band_2_num_of_cloud_free_samples_P90_GeoTIFF_TS1_', sorted, .9).percentile,
                        };
                        resolve({
                            compositionsOfBand2ForTS1: composition,
                            sorted: sorted,
                            thresholdsInfoForBand2ForTS1,
                        });
                    }).then(() => {
                        compositionsOfTS1.push(composition);
                    })
                    );
                    break;
                
            }
        })
    })
})
individualBandsDataForPathForTS2.map(async data => {
    data.map(load => {
        load.map((composition) => {
            switch(composition.band) {
                case SysConstants.CONST_BAND_1_RAW_NAME_IS_AVERAGES.description:
                    promisesTS2.push(new Promise((resolve, reject) => {
                        // ts2Compositions[0] = composition;
                        sorted = composition.contents.sort((a, b) => a-b);
                        thresholdsInfoForBand1ForTS2 = {
                            band1_minMaxNDVI_TS2: MathUtils.findMinMax('band_1_ndvis_averages_MinMaxGeoTIFF_TS2_', composition.contents),
                            band1_percentile10_TS2: MathUtils.findPercentile('band_1_ndvis_averages_P10_GeoTIFF_TS2_', sorted, .1).percentile,
                            band1_percentile90_TS2: MathUtils.findPercentile('band_1_ndvis_averages_P90_GeoTIFF_TS2_', sorted, .9).percentile,
                        };
                        resolve({
                            compositionsOfBand1ForTS2: composition,
                            sorted: sorted,
                            thresholdsInfoForBand1ForTS2,
                        });
                    }).then(() => {
                        compositionsOfTS2.push(composition);
                    })
                    );
                    break;
                case SysConstants.CONST_BAND_2_RAW_NAME_IS_NUM_OF_CLOUD_FREE_SAMPLES.description:
                    promisesTS2.push(new Promise((resolve, reject) => {
                        // ts2Compositions[1] = composition;
                        sorted = composition.contents.sort((a, b) => a-b);
                        thresholdsInfoForBand2ForTS2 = {
                            band2_minMaxNDVI_TS2: MathUtils.findMinMax('band_2_ndvis_averages_MinMaxGeoTIFF_TS2_', composition.contents),
                            band2_percentile10_TS2: MathUtils.findPercentile('band_2_ndvis_averages_P10_GeoTIFF_TS2_', sorted, .1).percentile,
                            band2_percentile90_TS2: MathUtils.findPercentile('band_2_ndvis_averages_P90_GeoTIFF_TS2_', sorted, .9).percentile,
                        };
                        resolve({
                            compositionsOfBand2ForTS2: composition,
                            sorted: sorted,
                            thresholdsInfoForBand2ForTS2,
                        });
                    }).then(() => {
                        compositionsOfTS2.push(composition);
                    })
                    );
                    break;
            }
        })
    });

2

Answers


  1. someFunction it is immediately called when you execute new Promise(someFunction). Same goes for anonymous functions, or for lists of anonymous functions returned by Array.map passed to Promise.all. Execution of that code does not happen when/where you await the Promise(s). You can’t delay their execution. If you want to control when they are executed then don’t build a list of Promises but a list of functions which you then await Promise.all(unitsOfWork.map(unit => unit()) or something similar.

    Login or Signup to reply.
  2. The code you have so far executes because you use await within nested .map() calls. To get the delayed execution using Promise.all, this is what you can do to modify it:

    1. Remove Await from Inner Loops:

    You remove the await from within the functions .map() that process the individual compositions. This is so that promise creation happens without waiting for each of the promises to resolve.
    2. Return Promises:

    Instead of forcing resolved data into arrays, change to return new promises from the .map() calls. These should resolve with the desired data after processing each composition.
    3. Update Outer .map() Calls
    In the outer .map() calls change back to using a plain function rather than an async function. This way the promises get collected without being run for each loop.

    const promisesTS1 = [];
    const promisesTS2 = [];
    
    Promise.all([
      individualBandsDataForPathForTS1.map(data => {
        return data.map(load => {
          return load.map(composition => {
            switch (composition.band) {
              case SysConstants.CONST_BAND_1_RAW_NAME_IS_AVERAGES.description:
                return new Promise((resolve, reject) => {
                  // ts1Compositions[0] = composition;
                  sorted = composition.contents.sort((a, b) => a - b);
                  thresholdsInfoForBand1ForTS1 = {
                    band1_minMaxNDVI_TS1: MathUtils.findMinMax('band_1_ndvis_averages_MinMaxGeoTIFF_TS1_', composition.contents),
                    band1_percentile10_TS1: MathUtils.findPercentile('band_1_ndvis_averages_P10_GeoTIFF_TS1_', sorted, .1).percentile,
                    band1_percentile90_TS1: MathUtils.findPercentile('band_1_ndvis_averages_P90_GeoTIFF_TS1_', sorted, .9).percentile,
                  };
                  resolve({
                    compositionsOfBand1ForTS1: composition,
                    sorted: sorted,
                    thresholdsInfoForBand1ForTS1,
                  });
                });
              case SysConstants.CONST_BAND_2_RAW_NAME_IS_NUM_OF_CLOUD_FREE_SAMPLES.description:
                return new Promise((resolve, reject) => {
                  // ts2Compositions[1] = composition;
                  sorted = composition.contents.sort((a, b) => a - b);
                  thresholdsInfoForBand2ForTS1 = {
                    band2_minMaxNDVI_TS1: MathUtils.findMinMax('band_2_ndvis_averages_MinMaxGeoTIFF_TS1_', composition.contents),
                    band2_percentile10_TS1: MathUtils.findPercentile('band_2_ndvis_averages_P10_GeoTIFF_TS1_', sorted, .1).percentile,
                    band2_percentile90_TS1: MathUtils.findPercentile('band_2_ndvis_averages_P90_TIFF_TS1_', sorted, .9).percentile,
                  };
                  resolve({
                    compositionsOfBand2ForTS1: composition,
                    sorted: sorted,
                    thresholdsInfoForBand2ForTS1,
                  });
                });
              default:
                return Promise.resolve(null); // Handle other cases if needed
            }
          });
        });
      }),
      individualBandsDataForPathForTS2.map(data => {
        return data.map(load => {
          return load.map(composition => {
            // Similar logic for TS2 data processing as TS1
            // ...
          });
        });
      }),
    ])
    .then(allPromises => { // This then block will be executed later
      // allPromises will be an array containing all resolved promises
      const processedDataTS1 = allPromises[0]; // Array of results from TS1 processing
      const processedDataTS2 = allPromises[1]; // Array of results from TS2 processing
      // Now you can access and use the processed data from each timeseries
      // ...
    });
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search