簡體   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