Kevin
Kevin

Reputation: 4848

Why doesn't 'await' wait?

I am new to await/async functions in Javascript. I wrote the following function:

getGoogleResults = async () => {
    const googleResultUrl = 'http://www.google.com/search?q=bakery&num=60');

    // get only Divs within results that have class of 's'
    $.getJSON(googleResultUrl, (data) => {
      const results = $(data.contents).find('div[class="g"]');
      const divs = results.find('div[class="s"]');
      console.log(data.contents); // data logged here looks fine in console
      return data.contents; 
    });
  }

This function works fine, I can log out the response to the console and see the data that was parsed out (top 60 Google results).

However, what I don't understand is when I call the function, I'm expecting it to wait until the promise is returned before continuing. But, that isn't the case. When I call the function, the program immediately runs the next line (a log to the console) without waiting:

async startProcess() {
    const googleResults = await this.getGoogleResults();
    console.log(googleResults); // this gets run immediately, produces 'undefined' in console
  }

And what gets logged to the console is 'undefined'. So, obviously, I'm doing something wrong, but I can't find an example that shows what that could be. It's like the program invokes the function but immediately moves on without waiting for the promise.

EDIT: I know my function is just returning data.contents at this point, instead of the parsed Divs. I'm just testing at this point and wanted to see results after calling the async function.

Upvotes: 0

Views: 175

Answers (2)

Ele
Ele

Reputation: 33726

You need to return a Promise object from the function getGoogleResults

getGoogleResults = () => { // You don't need the async keyword here
    return new Promise((resolve, reject) => {
        const googleResultUrl = 'http://www.google.com/search?q=bakery&num=60');
        // get only Divs within results that have class of 's'
        $.getJSON(googleResultUrl, (data) => {
          const results = $(data.contents).find('div[class="g"]');
          const divs = results.find('div[class="s"]');
          console.log(data.contents); // data logged here looks fine in console
          resolve(data.contents); // Use the function resolve.
        });

        // Use the function reject for any errors.
    }); 
}

Upvotes: 2

Dániel Kis-Nagy
Dániel Kis-Nagy

Reputation: 2505

You should return a Promise for your async function to actually be awaitable. Like this:

getGoogleResults = async () => {
    return new Promise((resolve, reject) => {
      const googleResultUrl = 'http://www.google.com/search?q=bakery&num=60');

      // get only Divs within results that have class of 's'
      $.getJSON(googleResultUrl, (data) => {
        const results = $(data.contents).find('div[class="g"]');
        const divs = results.find('div[class="s"]');
        console.log(data.contents); // data logged here looks fine in console
        resolve(data.contents); 
      }); //TODO call reject() on error
    }
}

Upvotes: 2

Related Questions