javascript - 为什么我的数据获取器函数返回未定义?
问题描述
我正在尝试使用 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;
});
}
解决方案
我上面的那个人说的是真的,你将所需的值返回给作为参数传递给的匿名函数回调google.maps.event.addListener(...)
。似乎您的函数行为是异步的,并且是一种返回值的方法,而您的代码使用 Promises 并没有进行太多更改。将您的函数设置为返回仅在回调内部解析的 Promise,并使用这些函数在代码中预先await
添加运行时的关键字,等待 promise 被解析(或拒绝)并获得所需的值。请注意,您只能await
在async
上下文中使用,所以如果它不适合您,那么您可以使用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 内部使用的匿名回调一致。
推荐阅读
- angular - 上传多个文件角度和springboot
- angular - 离子。ionic 错误。目标入口点“@ionic-native/geolocation”缺少依赖项:[ng] - @ionic-native/core
- azure - scriptrunconfig、runconfig 和 estimator 的区别
- css - Bootstrap 性能不佳 - custom-select resp select.form-control 冻结了几秒钟
- python-3.x - PySpark 读取子文件夹/目录中的所有 json 文件(使用通配符)并添加文件/文件夹名称
- ios - iOS webview http post到另一个新窗口不起作用
- ios - iphone 和 ipad 问题 - 引导卡底部的空白
- c# - 尝试通过代码创建递归索引时在 RavenDB 中获取 IndexCompilationException
- flutter - Flutter - 使用 AndroidAlarmManager 和 Location 获取位置
- java - 解密密码java游戏