繁体   English   中英

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

[英]Navigator - getCurrentPosition() promise resolves before location is found

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

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

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

下面是我的“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();

好的,所以我似乎找到了解决方案。 如果我可以做任何事情来改善它,或者如果有其他解决方案,请告诉我。 谢谢!

控制器:然而,大部分相同,我不再需要 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 类中。 我没有在 getCurrentPosition 函数之外解析 promise,而是将它传递给函数,并让它在解析时执行 '_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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM