【问题标题】:the code is executed before expected, async/await not working as expected代码在预期之前执行,async/await 没有按预期工作
【发布时间】:2021-10-09 09:07:15
【问题描述】:
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);
};

我想知道为什么 console.log 的输出是分配新值之前的状态对象,尽管我使用 async/await 来确保 console.log 是在更改对象值之后

【问题讨论】:

  • 因为navigator.geolocation.getCurrentPosition 不返回承诺,所以您的 await 立即解决,无需等待内部回调。

标签: javascript asynchronous async-await


【解决方案1】:

问题是navigator.geolocation.getCurrentPosition() 没有返回Promise。这是一个老式的基于回调的方法,所以await 什么都不做。为了在我们知道位置后运行console.log(),您需要将您的console.log() 放入回调函数中:

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
  });
};

但是,如果您愿意,可以将其设为异步函数。你可以这样做:

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);
};

总而言之,await 仅在函数或方法返回 Promise 时才有意义。

【讨论】:

    【解决方案2】:

    因为navigator.geolocation.getCurrentPosition 是一个函数,它返回void 而不是一个promise,所以你的await 语句没有任何效果。

    如果你确实想等待这段代码,你可以这样做

    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);
    
    

    【讨论】:

      【解决方案3】:

      这是因为await 只等待PromisesgetCurrentPosition() 不返回承诺。

      看一下界面:

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

      你会在最右边看到void,意思是undefined

      但是你可以像这样承诺你的功能:

      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);
      };
      

      【讨论】:

        猜你喜欢
        • 2019-12-04
        • 2021-03-11
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-05
        • 2016-11-09
        • 2016-08-21
        相关资源
        最近更新 更多