1

如何在不丢失值的情况下从异步函数设置对象的属性?另一个 SO 线程上的某个人说,与此函数有关的任何内容都应保留在函数内部。但是,我想从中分配值,并将其分配给一个对象。我对 OOP Js 有点陌生,所以这让我很困惑。

我有这个功能可以获取用户的位置。这个 HTML5 函数需要一个回调来传递一个位置对象。

function getInfo()
{
    navigator.geolocation.getCurrentPosition(getPos);
}

这是在 getCurrentPosition() 中引用的函数。

function getPos(position)
{
PositionObj.lat = position.coords.latitude;
PositionObj.lon = position.coords.longitude;
}

位置对象:

var PositionObj = 
{
lat:null,
lon:null,
returnLat: function()
             {
             return this.lat;
             },
returnLon: function()
             {
             return this.lon;
             }
};

当我尝试访问 PositionObj 的属性时,我得到 null,而不是回调分配的新值。我该怎么做呢?我已经尝试过将回调作为对象本身,并将值传递给另一个为对象分配值的函数。任何帮助,将不胜感激!

4

1 回答 1

1

最重要的问题是:您何时尝试访问PositionObj的属性?由于整个事情是异步的,因此在检索并分配位置之前lat或之前,您不会看到任何值。因此,一些同步的东西,比如:longetPos

getInfo();
console.log(PositionObj.lat);

绝对行不通。立即getInfo返回并且不等待位置进入。这是一件好事:关于异步的整个想法是你不要等待(阻塞)直到你得到你的结果。相反,您给该函数一个回调,并且该函数确保在稍后检索结果时调用它。好莱坞式:“别叫我,我叫你!”

因此,任何依赖于检索到的实际位置的东西都getInfo需要在回调中。这意味着您必须以不同的方式思考和编码:您需要将同步函数分解为更小的函数,这些函数作为回调链接起来。

在您的情况下,您可以将它console.log(PositionObj.lat)(或您想要对该位置做的任何其他事情)放入(您所称的)getPos(您可能想为该函数想一个更好的名称)。

这是一个更完整的示例,可以更好地演示该概念。在线商店的结帐页面上可能会显示如下内容:

var position = getPosition(); // using geolocation
var closestShop = getClosestShop(position); // using AJAX to a server-side script
alert("The closest shop is " + closestShop);

但是,所有这些同步调用都会阻止脚本的执行,并且页面会“冻结”。用户可能会认为他的浏览器崩溃了,这不是一个很好的用户体验。

如果所有这些操作都是异步的,您将对其进行重组,使其看起来像这样:

getPosition(function(position) {
    getClosestShop(position, function(closestShop) {
        alert("The closest shop is " + closestShop);
    });
});

在这里,每个函数都接受一个回调函数,它在结果出现时调用它。它们都立即返回,允许脚本继续执行并保持页面响应。当然,没有什么能阻止您在此回调中启动另一个异步操作,从而有效地将它们链接起来。

事实上,最后一种模式非常流行,以至于创建了一种新机制以使其更易于管理:promises。内部工作仍然相同(函数接受回调而不是同步阻塞),但看起来更令人愉快。当你做出getPositiongetClosestShop返回承诺时,你可以这样写:

getPosition().then(getClosestShop).then(function(closestShop) {
    alert("The closest shop is " + closestShop);
});
于 2013-06-23T09:58:48.313 回答