0

I'm using 3 region and using a aws configuration for output Timestamp and Average.

But I don't understand why I have a empty array in my output.

I add the different configuration, share cw object and getMetricStatistics method details.

I don't understand the method for response asynchronous call

Thanks for you help

var arr = [
    { "region": "eu-west", "value": "http://****" },
    { "region": "eu-west", "value": "http://****" },
    { "region": "eu-west", "value": "http://****" },
    ] ;  

var GlobalTab = [];

var r=-1;
    while ( arr[++r] ) {
    var region= arr[r].region; //test
    var Value = arr[r].value ; //test
    cw.getMetricStatistics(params, function(err, data) {
        if (err){
            console.log(err, err.stack); // an error occurred
        }
        else {   
            var TabJSON = [];
            for(var i=0;i<5;i++) {
                TabJSON.push(data.Datapoints[i]);
            }
        GlobalTab.push(TabJSON);
        function foo(){
        return new Promise( (resolve, reject) => { 
        setTimeout ( function(){    
        resolve(GlobalTab)// 
        }, 1000 )
        })
        }
        }
    });
}
console.log(GlobalTab); //error empty array
let bar ; 
foo().then( res => {
bar = res;
console.log(bar) // 
});

Expected result:

[[{Timestamp: 2019-01-15T08:26:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:32:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:26:00.000, Average: 200},
{Timestamp: 2019-01-15T08:29:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:35:00.000Z, Average: 200}],
[{Timestamp: 2019-01-15T08:26:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:32:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:26:00.000, Average: 200},
{Timestamp: 2019-01-15T08:29:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:35:00.000Z, Average: 200}],
[{Timestamp: 2019-01-15T08:26:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:32:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:26:00.000, Average: 200},
{Timestamp: 2019-01-15T08:29:00.000Z, Average: 200},
{Timestamp: 2019-01-15T08:35:00.000Z, Average: 200}]]

1 Answers1

0

You can split your code into multiple functions to better see what is going on. The problem you are facing is that you want to access value, that has been returned from an asynchronous call in a main function (global scope) which is not possible due to how asynchronous calls work.

First, lets write a function that takes just one region as an input and returns a promise holding the statistics for that region returned from the underlying cw.getMetricStatistics call.

function getRegionMetrics(regionParams) {
    return new Promise((resolve, reject) => {
        cw.getMetricStatistics(regionParams, function(err, data) {
            if (err) {
                console.log(err, err.stack);
                reject(err);
            } else {
                var TabJSON = [];
                for (var i = 0; i < 5; i++) {
                    TabJSON.push(data.Datapoints[i]);
                }
                resolve(TabJSON);
            }
        });
    });
}

Next, you need a function that will call the above function for each region that you want to process. Here, you can leverage map function to create an array of promises and Promise.all to resolve that array.

function getAllMetrics(regions) {
    return Promise.all(
        regions.map(regionParams => getRegionMetrics(regionParams))
    );
}

Your processing logic is done. Now, when you need to get statistics for an array of regions, simply call the getAllMetrics function and chain it with then method.

getAllMetrics(regions).then(res => {
    console.log(res); // here "res" is your "globalTab"
}).catch(err => {
    console.log(err);
});

Where regions is your arr.

Matus Dubrava
  • 13,637
  • 2
  • 38
  • 54