为什么不“等待”等待?

时间:2018-10-26 15:25:37

标签: javascript asynchronous async-await

我是Java中等待/异步功能的新手。我写了以下函数:

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; 
    });
  }

此功能正常工作,我可以注销对控制台的响应并查看已解析的数据(排名前60位的Google结果)。

但是,我不明白的是,当我调用该函数时,我希望它能等到返回promise后再继续。但是,事实并非如此。当我调用该函数时,该程序无需等待即可立即运行下一行(登录到控制台的日志):

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

登录到控制台的内容是“未定义”。因此,很明显,我做错了事,但是找不到一个示例来说明可能的情况。就像程序调用了函数一样,但是无需等待诺言就立即继续前进。

编辑:我知道我的函数此时仅返回data.contents,而不是解析的Div。我现在只是在测试,想在调用async函数后查看结果。

2 个答案:

答案 0 :(得分:2)

您需要从函数getGoogleResults返回一个Promise对象

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.
    }); 
}

答案 1 :(得分:2)

您应该为异步函数返回一个Promise,使其实际上可以等待。像这样:

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
    }
}