-1

I have a for loop like so:

var currentLargest
for (var site in sites) {
    // Each site is a website (www.mysite1.com, www.mysite2.com, etc.)
    $.getJSON(site).then(function(data) {
       if (data > currentLargest) {
           currentLargest = data
       }
    });
}
// Here is where I want to use "currentLargest"

It checks multiple different websites to get the largest value. However, I can't extract the data I need after the for loop. I can only interact with currentLargest from within the promise, but that data is only relevant for ONE of the sites (it hasn't finished looping through all them until after the for loop).

How can I access the currentLargest value after the for loop containing the getJSON promises?

AlwaysQuestioning
  • 1,464
  • 4
  • 24
  • 48
  • 1
    Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – zero298 Mar 07 '18 at 17:51
  • Basically that's not possible in the way you're imagining. Since the `getJSON` call is async, there is no way to access the `currentLargest` synchronously after the loop. You have to access that data via a `.then` function, like any other result that's based on an async operation. – CRice Mar 07 '18 at 17:51
  • @CRice How could I structure this, then? – AlwaysQuestioning Mar 07 '18 at 17:52
  • You'll want to put all the `getJSON` promises into an array, then use `Promise.all` to await the completion of all of them, then calculate the largest and do what you need with it in the `.then` of that `Promise.all`. – CRice Mar 07 '18 at 17:58
  • @CRice I'm trying this implementation, but having trouble figuring out how to transcribe my `sites` array into `Promise.all()`. If you have time, could you show me an example? – AlwaysQuestioning Mar 07 '18 at 18:58

2 Answers2

1

// Your code:
/*
var currentLargest
for (var site in sites) {
    // Each site is a website (www.mysite1.com, www.mysite2.com, etc.)
    $.getJSON(site).then(function(data) {
       if (data > currentLargest) {
           currentLargest = data
       }
    });
}
*/

// Updated:
const sitePromisesArr = sites.map((site) => $.getJSON(site));

$.when(sitePromisesArr)
  .then((valArr, index) => {
    // The "valArr" here will be an Array with the responses
    const largest = valArr.reduce((current, next) => next > current ? next : current, 0);
    
    // This will be the largest value.
    console.log(largest);
    
    // This will be the site that contains the largest value.
    console.log(sitePromisesArr[index]);
  });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
th3n3wguy
  • 3,649
  • 2
  • 23
  • 30
-1

You need to use a async loop and then execute a callback once all the async getJSON requests are finished. You could use http://caolan.github.io/async/docs.html#each to help with this.

Rush
  • 179
  • 6