Home > other >  the code is executed before expected, async/await not working as expected
the code is executed before expected, async/await not working as expected

Time:10-10

export const state = {
  lat: "",
  lng: "",
};

// Setting the map

//gets lat and lng and from the browser.

export const addHandlerSetPosition = async function (handler) {
  await navigator.geolocation.getCurrentPosition(function (pos) {
    state.lng = pos.coords.longitude;
    state.lat = pos.coords.latitude;

    handler(state.lng, state.lat);
  });
  console.log(state);
};

i want to know why the output of the console.log is the state object before assigning the new values although i used async/await to make sure that the console.log is after changing object values

CodePudding user response:

The problem is that navigator.geolocation.getCurrentPosition() doesn't return a Promise. It's an old-fashioned callback-based method, so doing await does nothing. In order to run console.log() after we know the position, you need to put your console.log() inside the callback function:

export const addHandlerSetPosition = function (handler) {
 navigator.geolocation.getCurrentPosition(function (pos) {
    state.lng = pos.coords.longitude;
    state.lat = pos.coords.latitude;

    handler(state.lng, state.lat);

    console.log(state); // here
  });
};

You can, however, make it an async function if you'd like. Here's how you can do it:

function getPosition(options) {
  return new Promise((resolve, reject) => {
    navigator.geolocation.getCurrentPosition(
      resolve,
      reject,
      options
    );
  });
}

export const addHandlerSetPosition = async function (handler) {
  const pos = await getPosition(); // now await works!

  state.lng = pos.coords.longitude;
  state.lat = pos.coords.latitude;

  handler(state.lng, state.lat);

  console.log(state);
};

To sum up, await only makes sense if a function or method returns a Promise.

CodePudding user response:

Because navigator.geolocation.getCurrentPosition is a function, that returns void instead of a promise, so your await statement gives no effect. enter image description here

If you do want to await this code, you can do something like this

const getPosition = new Promise((resolve) => {
    navigator.geolocation.getCurrentPosition((position) => {
        resolve(position);

    })
});

const state = {
    lat: "",
    lng: "",
};
  
position = await getPosition;
state.lat = position.coords.latitude;
state.lng = position.coords.longitude;
console.log('State is: ', state);

CodePudding user response:

Its because await only waits on Promises and getCurrentPosition() does not return an promise.

Take a look at the interface:

interface Geolocation {
    clearWatch(watchId: number): void;
    getCurrentPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): void;
    watchPosition(successCallback: PositionCallback, errorCallback?: PositionErrorCallback | null, options?: PositionOptions): number;
}

You see at the very right it says void that means undefined

However you can promisfy your function like:

function getPos(){
  return new Promise((res, rej) => {
    navigator.geolocation.getCurrentPosition(res, rej)
  })
}

export const addHandlerSetPosition = async function (handler) {
  let pos = await getPos()
    
  state.lng = pos.coords.longitude;
  state.lat = pos.coords.latitude;
  handler(state.lng, state.lat);
  console.log(state);
};
  • Related