首页 > 解决方案 > 为什么我的数据获取器函数返回未定义?

问题描述

我正在尝试使用 Google API 来获取从电子表格中抓取的地址的 lat/lng 并将输出返回到 HTML 表中。我不确定在 getLat 和 getLong 函数中放入什么,因为它们返回“未定义”。下面是我的代码:

function getCoords(tableID)
{
var oTable = document.getElementById(tableID);
var rowLength = oTable.rows.length;

var tblHeadObj = document.getElementById(tableID).tHead;
var newTH = document.createElement('th');
tblHeadObj.rows[0].appendChild(newTH);
newTH.innerHTML = 'Latitude'
var newTH2 = document.createElement('th');
tblHeadObj.rows[0].appendChild(newTH2);
newTH2.innerHTML = 'Longitude'

var tblBodyObj = document.getElementById(tableID).tBodies[0];
for (var i=0; i<tblBodyObj.rows.length; i++) {
    for (k = 1; k < rowLength; k++){
        var oCells = oTable.rows.item(k).cells;
        var cellLength = oCells.length;
        var totalVal = '';

        for(var j = 2; j < cellLength; j++){
            var cellVal = oCells.item(j).innerHTML;        
            var newCell = tblBodyObj.rows[i].insertCell(-1);
            var newCell2 = tblBodyObj.rows[i].insertCell(-1);
            var value = cellVal + ' ';
            totalVal = totalVal + value;
        }
        newCell.innerHTML = getLat(totalVal);
        newCell2.innerHTML = getLong(totalVal);
        i++;
    }
    }
}

function getLat(tableVal){
    var autocomplete = new google.maps.places.Autocomplete(tableVal);

    google.maps.event.addListener(autocomplete, 'place_changed', function() {
      var place = autocomplete.getPlace();
      var lat = place.geometry.location.lat();
      document.getElementById("latitude").value = lat;
      return lat;
    });
  }
  
function getLong(tableVal){
    var autocomplete = new google.maps.places.Autocomplete(tableVal);

    google.maps.event.addListener(autocomplete, 'place_changed', function() {
      var place = autocomplete.getPlace();
      var lng = place.geometry.location.lng();
      document.getElementById("longitude").value = lng;
      return lng;
    });
}

标签: javascripthtml

解决方案


我上面的那个人说的是真的,你将所需的值返回给作为参数传递给的匿名函数回调google.maps.event.addListener(...)。似乎您的函数行为是异步的,并且是一种返回值的方法,而您的代码使用 Promises 并没有进行太多更改。将您的函数设置为返回仅在回调内部解析的 Promise,并使用这些函数在代码中预先await添加运行时的关键字,等待 promise 被解析(或拒绝)并获得所需的值。请注意,您只能awaitasync上下文中使用,所以如果它不适合您,那么您可以使用Promise.then(...)and/orPromise.catch(...)每个函数返回的 Promise 上的方法将一个回调传递给这些方法,以处理您的 Promise 的已解决和已拒绝上下文(在那里您将获得您想要的值来做任何您想做的事情)。

代码示例:

function example(arg) {
    return new Promise((resolve, reject) => {
        //code...
        google.maps.event.addListener(autocomplete, 'place_changed', ((resolve, reject) => function (){
            var place = autocomplete.getPlace();
            var lng = place.geometry.location.lng();
            document.getElementById("longitude").value = lng;
            resolve(lng);
        })(resolve, reject));
    });
}

example()
.then(function (lng){
    // Do whatever you want with your lng
}).catch(function (reason) {
    // If you use anywhere the `reject` callback of promise, that'll lead you here in
    // catch callback, or in second callback argument of `.then()` if you return another
    // promise inside `.then()` callback.
});

// ...

async function foo(){
    // ...

    // Be careful with rejections using await. await forces rejections
    // to throw exceptions so be sure to handle them with `try..catch` blocks.
    let lng = await example();

    // ...
}

上面的代码使用 Promise 来轻松保持异步行为,并使用 Closures 来确保 Promise 的上下文与 Promise 内部使用的匿名回调一致。


推荐阅读