如何从 JS 中的异步操作中获取值?



我读过一些论坛,看过一些关于异步操作和使用承诺来解决这类问题的 youtube 视频,但他们只在研究更简单的功能等等。 它实际上并没有给我如何解决我的问题的提示。 我的脚本中有这个函数。

var coordinates = [];
$(function(){
function getcoordinates(){
if(navigator.geolocation){
var options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
function success(pos) {
var crd = pos.coords;
userlat = crd.latitude;//this one
userlong = crd.longitude;// and this one are the ones i want
}
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
navigator.geolocation.getCurrentPosition(success, error, options);//but I dont have an idea how to access those two from this API function.
}
else
alert("Geolocation is not supported by this browser.");
}
$('#go').click(function(){
console.log("outside success output: " + userlat);//this still shows 0
console.log(coordinates);
$.ajax({
url:"dbphp.php",
method:"POST",
data:{userlong:coordinates[1], userlat:coordinates[2]},
success:function(data){
}
})
})
})

如何返回 userLAT 和 Userlong 的值并将其放入我的坐标数组中?

首先,让我们就您所谓的"异步"的定义达成一致:一段非阻塞代码,稍后将在满足条件时执行,对吗?

根据这个定义,您的代码中有一些"异步"调用,navigator.geolocation.getCurrentPosition()$.ajax(),但也.click()$()

每个都将回调您提供的函数(回调(。

getCurrentPosition()的情况下,它接收 3 个参数,其中 2 个分别是在成功/失败时执行的回调(可选(,以及一个配置对象(可选(。你肯定处理得很好。

但:

  1. 您的语法似乎有点错误,getcoordinates()按钮单击之前不会触发任何内容
  2. 无论哪种方式,您都不会在处理.click()处理程序中的返回值之前专门等待getcoordinates()完成
  3. 你不应该不必要地限定函数定义的范围
  4. userlatuserlong声明在哪里?
  5. 不要忘记数组是 0 索引的

TL;DR玩弄这个:

function getCoordinates(thenCb, errorCb) {
thenCb = thenCb || function () {};
errorCb = errorCb || function () {};
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
});
} else {
alert('Geolocation is not supported by this browser.');
}
}
$(function () {
$('#go').click(function () {
getCoordinates(function (pos) {
$.ajax({
url: 'dbphp.php',
method: 'POST',
data: { 
userlong: pos.coords.latitude, 
userlat: pos.coords.longitude 
},
success: function (data) {
// do stuff with data...
}
});
}, function (err) {
console.warn('Geolocation error ' + err.code + ': ' + err.message);
});
});
});

对于 ES6+ 版本:

const getCoordinates = (thenCb = () => {}, errorCb = () => {}) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
});
} else {
alert('Geolocation is not supported by this browser.');
}
};
$(() => {
$('#go').click(() => {
getCoordinates(({ coords }) => {
const { userlong, userlat } = coords;
$.ajax({
url: 'dbphp.php',
method: 'POST',
data: { userlong, userlat },
success: (data) => {
// do stuff with data...
}
});
}, (err) => {
console.warn(`Geolocation error ${err.code}: ${err.message}`);
});
});
});

注意 1:您可能希望根据您的需求和上下文重构它,避免在全局范围内设置getCoordinates()等。

注意 2:在这种情况下,可以等待用户单击时完成getCoordinates()因为尽管"异步",但该函数确实会迅速返回结果。通常,当解析时间较长时,您可能希望 a( 在单击处理程序之前触发函数以记住其返回值,b( 向用户显示加载状态。

关于 xhr 请求,请注意,您使用的是jQuery.ajax(),响应数据将在作为其第一个参数提供的success回调中可用。

另外,请务必查看文档:
- https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
- https://api.jquery.com

如果有兴趣,请阅读如何使用 Promises,使回调代码更加摘要化:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

如果仍然感兴趣,请阅读如何使用async/await使Promises代码更加摘要化:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

相关内容

最新更新