导航器 - getCurrentPosition() 承诺在找到位置之前解析

Navigator - getCurrentPosition() promise resolves before location is found

此代码用于 'zillow' 克隆作为投资组合项目。

我的问题:我承诺使用地理定位检索用户的位置 API。我需要此代码异步 运行 但是,当代码执行时,它会在找到用户位置之前解决承诺。当我将代码的某些部分包装在超时函数中时,代码会起作用,但我真的想只使用承诺来解决这个问题。我该如何解决这个问题?非常感谢您的帮助!

P.S:我还没有编写我的错误处理程序,我想在这样做之前解决上述问题。此外,如果您需要任何其他文件,请告诉我,我会上传它们,但我认为问题出在下面显示的两个文件中的任何一个

下面是我的 'controller.js' 文件中的代码:

const controlSearchCurrentLocation = async function () {

  await findLocationView.getUserLocation(model.storeCurrentLocation);

  /*
   The setTimeout function is only used in order to give the 
   'findLocationView.getUserLocation(model.storeCurrentLocation)' time 
   to find and store the user's location
  */

  setTimeout(() => {
    currentCityResultsView.displayResults(
      model.sendCurrentCityState,
      model.storeData,
      model.sendCoords,
      model.sendHomesCurrentLocation,
      model.sendHomesLength
    );
  }, 4000);
};

const init = function () {
  controlSearchCurrentLocation();

  controlSearch();
};

init();

以下来自我的 'findLocationView.js' 文件:

class FindLocationView extends AppView {

  getUserLocation(storeCurrentLocationFunc) {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition(
        function (position) {
          this._success(position, storeCurrentLocationFunc);
        }.bind(this),
        this._failure,
        this._options
      );

      if (navigator.geolocation) resolve("stored user location");
      if (!navigator.geolocation) reject("could not store user location");
    });
  }

  async _success(position, storeCurrentLocationFunc) {
    let city, state;
    const { latitude, longitude } = position.coords;
    [...this._coordinates] = [latitude, longitude];
    [this._latitude, this._longitude] = [latitude, longitude];

    mapView.initMap(this._coordinates);

    const data = await helpers.ajaxLocation(this._latitude, this._longitude);

    city = data.results[0].address_components[2].long_name;
    state = data.results[0].address_components[4].short_name;
    storeCurrentLocationFunc(this._coordinates, city, state);
  }

  _failure(error) {
    console.warn(`ERROR(${error.code}): ${error.message}`);
  }

  _options = {
    enableHighAccuracy: true,
  };
}

export default new FindLocationView();

好的,看来我找到了解决办法。如果我能做些什么来使它变得更好,或者如果有其他解决方案,请告诉我。谢谢!

Controller:但大部分相同,我不再需要 setTimeout 函数,因为 controlSearchCurrentLocation 函数似乎正在异步执行代码。 (见下文)

const controlSearchCurrentLocation = async function () {

  await findLocationView.getUserLocation(model.storeCurrentLocation);

  currentCityResultsView.displayResults(
    model.sendCurrentCityState,
    model.storeData,
    model.sendCoords,
    model.sendHomesCurrentLocation,
    model.sendHomesLength
  );
};

const init = function () {
  controlSearchCurrentLocation();

  controlSearch();
};



init();

我最大的修正是在我的 findLocationView 中 class。而不是解决 getCurrentPosition 函数之外的承诺,我将它传递给函数,并让它在解析时执行“_success”函数。这使得承诺无法在找到用户位置之前解决。

class FindLocationView extends AppView {

  getUserLocation(storeCurrentLocationFunc) {
    return new Promise((resolve, reject) => {
      navigator.geolocation.getCurrentPosition(
        function (position) {
          resolve(this._success(position, storeCurrentLocationFunc));
        }.bind(this),
        this._failure,
        this._options
      );

      if (!navigator.geolocation) reject("could not store user location");
    });
  }

  async _success(position, storeCurrentLocationFunc) {
    let city, state;
    const { latitude, longitude } = position.coords;
    [...this._coordinates] = [latitude, longitude];
    [this._latitude, this._longitude] = [latitude, longitude];

    mapView.initMap(this._coordinates);

    const data = await helpers.ajaxLocation(this._latitude, this._longitude);

    city = data.results[0].address_components[2].long_name;
    state = data.results[0].address_components[4].short_name;
    storeCurrentLocationFunc(this._coordinates, city, state);
  }

  _failure(error) {
    console.warn(`ERROR(${error.code}): ${error.message}`);
  }

  _options = {
    enableHighAccuracy: true,
  };
}

export default new FindLocationView();

虽然你设法解决了。您最终遇到问题的原因是混合问题。

  const userLocation = await findLocationView.getUserLocation();

理想情况下,您希望 getUserLocation 解析位置,仅此而已。它不存储位置。

navigator.geolocation.getCurrentPosition(resolve, reject);

现在你有了关注点分离

// getUserLocation no longer takes a param
const userLocation = await findLocationView.getUserLocation();
// Wait until userLocation is stored
await _success(userLocation, model.storeCurrentLocation);
// We can now show results
currentCityResultsView.displayResults();