0
async function tempfunc2(result) {
  return new Promise((resolve, reject) => {

    for(var i = 0; i < result.length; i++)
    {
      var url = "SomeURLGeneratedByPreviousFunction";

      $.getJSON(url, function(data) {

        if (data.mappings["0"]) {
          gameHashes.push(data.mappings["0"].game);
        }
      });
    }

    return resolve(gameHashes);
  });
}

I have this code block that is getting and populating data. Its handling quite a bit of data, so it takes some time.

What I want is for this function to complete before finishing because the next lines of code rely on the result of this function.

However, the way its currently built, it will return the Hashes before the function is complete. How do I await this jQuery function?

I tried putting a .then() after the $.getJSON, but it didn't change much.

I also tried putting this particular piece in a different function to try and await it, but that did not work either

await tempfunc().then(tempfunc2);

This is what calls tempfunc2.

Marcos Dimitrio
  • 6,651
  • 5
  • 38
  • 62
  • I think try to use generator functions `async *` instead of asynchronous function that return just a future, the generator function doesn't get the next one until the first one ends completely. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function* – user9335240 Jan 27 '19 at 22:27
  • 3
    Possible duplicate of [function wait with return until $.getJSON is finished](https://stackoverflow.com/questions/10775787/function-wait-with-return-until-getjson-is-finished) – Sebastian Waldbauer Jan 27 '19 at 22:28
  • 1
    You should probably work on improving your indentation as well. Having readable code makes solving issues like this a lot easier. – Patrick Roberts Jan 27 '19 at 22:30
  • 1
    I went ahead and fixed the indentation for you. In the future please use proper formatting in your code blocks. You can paste HTML, CSS, or JavaScript snippets in the Stack Snippet modal by clicking the `< >` button in the editor, and use the "Tidy" button to automatically format your code for you. – Patrick Roberts Jan 27 '19 at 22:35
  • @PatrickRoberts tried to also fix indentation, apologies. adding .then(() => console.log("game hash logged")) did not work, I need the function to finish completely, and THEN resolve. using or not using async doesn't make a difference here. – Rizwan Mohammed Jan 27 '19 at 22:41
  • 1
    `gameHashes` doesn't exist in the scope. If it was defined in enclosing scope, this doesn't look very good. – Estus Flask Jan 27 '19 at 22:52

2 Answers2

3

You need to resolve the promise once you get the response from $.getJSON.

Something like this:

async function tempfunc2(result) {
  return new Promise((resolve, reject) => {
    $.getJSON(url, function(data) {
      if (data.mappings["0"]) {
        gameHashes.push(data.mappings["0"].game);
      }
      resolve(gameHashes)
    });
  })
}

Make sure gameHashes is defined as an array.

From the edits to your question it seems that you're making multiple &.getJSON calls. In that case, you need to do something like this:

function tempfunc2(result) {
  return new Promise(async resolve => {
    const promises = result.map(value => {
      return new Promise(resolve => {
        $.getJSON(url, function(data) {
          resolve(data)
        });
      });
    })

    let results = await Promise.all(promises)
    results = results.filter(v => v.mapping && v.mapping["0"]).map(v => v.mapping["0"].game)

    resolve(results);
  });
}
Titus
  • 22,031
  • 1
  • 23
  • 33
  • This works, but I need it to resolve after ALL of the data has been retrieved and stored. Please see updated post. What's happening is that its being resolved before all of the data has been collected and stored. – Rizwan Mohammed Jan 27 '19 at 23:10
  • I had to modify this a bit to function and get what I needed, but it pointed me in the right direction. Thanks! The async resolve I think is what I needed. – Rizwan Mohammed Jan 28 '19 at 06:17
1

new Promise is known as promise construction antipattern in cases when a promise already exists.

$.getJSON returns jQuery deferred object, it can produce a promise that can be awaited:

  async function tempfunc2(result) {
    const data = await $.getJSON(url).promise();
    if (data.mappings["0"])
      gameHashes.push(data.mappings["0"].game);

    return gameHashes;
  }
Estus Flask
  • 206,104
  • 70
  • 425
  • 565