如何相互依赖地执行多个异步函数?

How to execute multiple async functions depending on each other?

看来我理解 async/await 的行为,但现在-现在我深深地被我的问题困住了,无法解决它。 我正在尝试创建天气应用程序,因此我需要先请求纬度和经度,然后获取该信息以向天气 API 发送请求并获取预报。正如 google 文档

中所述

Accessing the Geocoding service is asynchronous since the Google Maps API needs to make a call to an external server.

所以我正在尝试使用async/await来处理它。

import Search from './models/Search';
import * as searchView from './views/searchView';
import { elements } from './views/base';

/*
* Search controller
*/

const state = {

};

const controlSearch = async () => {
  const query = searchView.getInput();

  if (query) {
    state.forecast = new Search(query);

    try {
      await state.forecast.codeAddress();
      await state.forecast.getForecast(state.forecast);
      console.log(state);
    } catch (error) {
      console.log(error);
    }
  }
};

elements.searchForm.addEventListener('submit', (e) => {
  e.preventDefault();
  controlSearch();
});

这是我的控制器。在底部,我将 eventListener 放入 form 中,用户将使用它来搜索城市,然后获取它的预报。

这是我的搜索模型

import { key, proxy } from '../config';

export default class Search {
  constructor(query) {
    this.query = query;
  }

  codeAddress() {
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({ address: this.query }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
      }
    });
  }

  async getForecast(geometry) {
    console.log(geometry, 'geometry');
    const result = await fetch(`${proxy}https://api.darksky.net/forecast/${key}/${geometry.latitude},${geometry.longitude}`);
    const forecast = await result.json();
    forecast.then((res) => {
      this.forecast = res;
    });
  }
} 

问题是当向 darkSky API 请求时,geometry.latitude 和几何经度未定义。

How can i handle this problem ?

codeAddress 没有 await 任何东西或 return 要 await 编辑的东西。即使 geocode 尚未完成,它也会立即关闭。让它 return 一个 Promise 可以 awaited.

codeAddress() {
  return new Promise((resolve, reject) => {
    const geocoder = new google.maps.Geocoder();
    geocoder.geocode({
      address: this.query
    }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
        resolve();
      } else {
        reject();
      }
    });
  });
}


不幸的是,您将需要手动 return 一个 Promise 因为 Geocoder.geocode() API 仅遵循异步回调样式并且 await 只会等待 .then()-ables(如 Promise)。

codeAddress 是异步的(因为响应是在回调中处理的),但您并未将其视为异步。试试这个:

async codeAddress() {
  const geocoder = new google.maps.Geocoder();
  return new Promise((resolve, reject) => {
    geocoder.geocode({ address: this.query }, (results, status) => {
      if (status === 'OK') {
        this.latitude = results[0].geometry.location.lat();
        this.longitude = results[0].geometry.location.lng();
        console.log(this.latitude, this.longitude, 'lat long');
        resolve();
      } else {
        reject();
      }
    });
  });
}

当然还有其他方法可以将带有回调的函数转换为异步函数。