簡體   English   中英

使用async / await從回調中獲取數據並僅在解決承諾后返回值

[英]Using async/await to get data from a callback and return a value only after a promise is resolved

我正在嘗試使用async / await,但我認為我對某些事情有誤解。

基本上,我正在嘗試使用Google Maps API計算位置列表和一個指定位置之間的距離。

這是我要執行的操作的粗略示例: https : //jsfiddle.net/qu5y69rj/1/

您可以看到該函數的結果undefined 3次,而不是我所期望的,對於我的示例,每次調用的結果是{distance: "ZERO_RESULTS"}

getDistance = async (start, end) => {
  const origin = new google.maps.LatLng(start[0], start[1]);
  const final = new google.maps.LatLng(end[0], end[1]);
  const service = new google.maps.DistanceMatrixService();
  let result; //need to return this value!
  await service.getDistanceMatrix(
    {
        origins: [origin],
      destinations: [final],
      travelMode: 'DRIVING'
    }, (response, status) => {
      if(status === 'OK') result = {distance: response.rows[0].elements[0].status}
    }
  )
  return result;
}

為什么在解決諾言之前返回結果? 只有兌現了承諾,我如何才能返回result的值? 據我了解,通過告訴javascript等待,我是說直到這個諾言得以解決之前,不要前進。 那不對嗎? 我很困惑,這讓我拔頭發。 任何幫助表示贊賞。

service.getDistanceMatrix接受回調,這意味着ti最有可能不返回承諾。

但是,異步功能會帶來希望。

作為解決方法,您可以將getDistanceMatrix包裹在一個getDistanceMatrix中(或使用另一個返回getDistanceMatrix方法):

const getDistanceMatrix = (service, data) => new Promise((resolve, reject) => {
  service.getDistanceMatrix(data, (response, status) => {
    if(status === 'OK') {
      resolve(response)
    } else {
      reject(response);
    }
  })
});

getDistance = async (start, end) => {
  const origin = new google.maps.LatLng(start[0], start[1]);
  const final = new google.maps.LatLng(end[0], end[1]);
  const service = new google.maps.DistanceMatrixService();
  const result = await getDistanceMatrix(
    service,
    {
      origins: [origin],
      destinations: [final],
      travelMode: 'DRIVING'
    }
  )
  return {
    distance: result.rows[0].elements[0].status
  };
};

使用JavaScript進行異步操作的方法有以下三種:

  1. 回調 :函數接受回調作為其最終參數。 它不返回任何內容( undefined ),並且在異步操作完成時,將調用回調。
  2. Promises :函數返回一個Promise,該函數在完成時將解析為異步操作的結果。
  3. Async / Await :函數返回一個Promise,並且可以使用async關鍵字在其定義內獲取異步操作的值。 使用return關鍵字返回的任何內容都將包裝在promise中。

由於getDistanceMatrix接受回調,因此不返回任何內容。 代碼中使用的await關鍵字不需要等待; 它立即獲得getDistanceMatrix返回的undefined值。 當操作完成並調用回調時, getDistance早已完成執行並返回。

您需要包裝getDistanceMatrix以便它返回一個promise,使getAllDistance()返回一個promise,並在console.log()語句中等待該promise:

const coords = [
  ['-36.22967', '-125.80271'],
  ['54.06395', '54.06395'],
  ['-5.00263', '-137.92806']
];

function getDistance (start, end) {
  const origin = new google.maps.LatLng(start[0], start[1]);
  const final = new google.maps.LatLng(end[0], end[1]);
  const service = new google.maps.DistanceMatrixService();

  return new Promise((resolve, reject) => {
    service.getDistanceMatrix(
    {
        origins: [origin],
      destinations: [final],
      travelMode: 'DRIVING'
    }, (response, status) => {
      if(status === 'OK') {
        resolve({ distance: response.rows[0].elements[0].status });
      } else {
        reject(new Error('Not OK'));
      }
    }
  );
  });
}

function getAllDistance (starts, end) {
  const promisedDistances = starts.map((start) => getDistance(start, end));
  // Promise.all turns an array of promises into a promise
  // that resolves to an array.
  return Promise.all(promisedDistances);
}

getAllDistance(coords, ['-30.23978', '-161.31203'])
  .then(result => { console.log(result); });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM