0

我正在尝试与基于纬度和经度数据的 Google Maps API 标记位置进行交互。我还想根据这个纬度和经度获取时区信息。为此,我使用了另一个外部 API,它接收纬度和经度并返回时间偏移量。然而,我的问题是,这一次数据在页面加载后返回。

在为用户加载页面后将此信息添加到页面的最佳方法是什么?我开始考虑使用回发,但在做了一些研究之后,我认为这不是解决我问题的正确方法。

4

1 回答 1

1

在浏览器中,JavaScript 允许您在页面加载后联系服务器。这称为异步请求,是“AJAX”(异步 Java 和 XML)中的第一个“A”。

X 可能有点用词不当,因为人们很乐意通过这种机制传递整个 HTML 块、JSON(AJAJ?)或其他形式的数据而不是 XML。

我总是会使用一个框架(我个人的选择是 JQuery)来执行操作,因为框架编写者已经完成了让你跨浏览器工作的工作。

你可以使用这个:

http://api.jquery.com/jQuery.get/ 或者如果返回数据是 JSON, http://api.jquery.com/jQuery.getJSON/

这个函数是 JQuery 的一部分,一旦数据被加载,就会执行一个回调函数。然后,您的回调函数可以使用 JQuery 选择器来查找和更新有问题的元素。

如果您使用特定的代码示例更新您的问题,我可以更具体地回答我的问题。

看到代码示例后编辑:

看起来您的问题实际上是确定代码执行顺序之一。您的代码遵循此模式(稍微简化并重新排列):

    var startTimeZone;

    jQuery(document).ready(function($) {
      $.ajax({
        url: "http://www.worldweatheronline.com/feed/tz.ashx?key=SecretKey&q=" + start_locale + "&format=json",
        dataType: "jsonp",
        success: function(parsed_json) {
          startTimeZone = parsed_json.data.time_zone[0].utcOffset;
          console.log("Callback: " + startTimeZone);
        },
        error: function(parsed_json) {

        }
      });
    });


    console.log("Main:" + startTimeZone);

首先,不需要将 ajax 命令包装在文档就绪回调中 - 只需对整个代码执行一次,无论入口点在哪里。(我认为这是一种将执行延迟到以下代码之后的尝试。)(这里还有更多要学习的内容 - JQuery 为您提供了多个事件来帮助初始化您的代码并使用 DOM,请参阅窗口。 onload 与 $(document).ready()的简要说明)

如果您运行上面的代码片段,您会发现控制台日志可能会显示:

Main: Undefined
Callback: [StartTimeZone]

其中 [StartTimezone] 是来自服务器的响应。ajax 命令是异步的,这意味着它会启动并执行它的操作,只要它需要就可以,让代码在它之后运行,就好像什么都没发生一样。完成后,它会适当地调用“成功”或“错误”回调。因此,在定义变量之前调用“主”控制台日志。之后,对 ajax 调用的响应会触发回调 - 因此输出 StartTimeZone。

如果您不熟悉回调或习惯于不支持它们或经常使用它们的语言(如 PHP),您可能希望或希望代码在 ajax 调用时暂停,然后运行回调,然后继续与其余的代码。显然情况并非如此。

在这种简单的情况下,我只需将处理时区的代码移动到回调中,但您的代码还有一个问题 - 您需要两个值,您似乎需要通过单独的调用来检索它们。

在这种情况下,我们需要在运行使用它们的代码之前确保我们拥有这两个值。我们应该怎么做?

一个简单的解决方案是:

var startTimeZone;
var endTimeZone;

      $.ajax({
        url: "http://www.worldweatheronline.com/feed/tz.ashx?key=SecretKey&q=" + start_locale + "&format=json",
        dataType: "jsonp",
        success: function(parsed_json) {
          startTimeZone = parsed_json.data.time_zone[0].utcOffset;
          getEndTimeZone();
        },
        error: function(parsed_json) {
          //console.log("Error: " + parsed_json);
        }
      });



function getEndTimeZone() {
      $.ajax({
        url: "http://www.worldweatheronline.com/feed/tz.ashx?key=SecretKey&q=" + end_locale + "&format=json",
        dataType: "jsonp",
        success: function(parsed_json) {
          endTimeZone = parsed_json.data.time_zone[0].utcOffset;
          console.log(endTimeZone);
          processTimeZones();
        },
        error: function(parsed_json) {
          //console.log("Error: " + parsed_json);
        }
      });
}

function processTimeZones() {
    var timeZoneDifference = (endTimeZone * 3600000) - (startTimeZone * 3600000);
    // Do the rest of your processing here
}

函数在被调用之前不会运行。此外,JavaScript 中的函数可以访问其包含范围内的变量(这意味着函数可以访问 startTimeZone 和 endTimeZone,它们是在函数本身之外定义的。)

上面的代码将在第一次 ajax 调用成功时调用 getEndTimeZone。getEndTimeZone 然后使用 ajax 调用来获取结束时区,然后在成功时调用 process 函数。这个函数肯定可以访问你需要的变量。

当然,我们现在在队列中等待处理两个请求。我们可以通过同时调用两者来加快速度,同时调用 process 函数,然后在进行处理之前确定我们是否有我们需要的数据:

var startTimeZone;
var endTimeZone;

      $.ajax({
        url: "http://www.worldweatheronline.com/feed/tz.ashx?key=SecretKey&q=" + start_locale + "&format=json",
        dataType: "jsonp",
        success: function(parsed_json) {
          startTimeZone = parsed_json.data.time_zone[0].utcOffset;
          processTimeZones();
        },
        error: function(parsed_json) {
          //console.log("Error: " + parsed_json);
        }
      });



      $.ajax({
        url: "http://www.worldweatheronline.com/feed/tz.ashx?key=SecretKey&q=" + end_locale + "&format=json",
        dataType: "jsonp",
        success: function(parsed_json) {
          endTimeZone = parsed_json.data.time_zone[0].utcOffset;
          console.log(endTimeZone);
          processTimeZones();
        },
        error: function(parsed_json) {
          //console.log("Error: " + parsed_json);
        }
      });

function processTimeZones() {
  if (startTimeZone != undefined && endTimeZone != undefined)
  {
    var timeZoneDifference = (endTimeZone * 3600000) - (startTimeZone * 3600000);
    // Do the rest of your processing here
  }
}

无论哪个 ajax 调用首先返回,都会调用 process 函数。但是,其中一个变量将未定义,因此 if 条件将失败并且函数将静默返回。当第二个结果出现时,两个变量都将被设置。现在将满足 if 条件并且将运行处理代码。

有 1001 种方法可以给众所周知的猫剥皮,但希望这些方法能让您开始有效地使用回调。

当然,所有这些都忽略了您已将 ajax 调用置于 for 循环中的事实。如果您需要执行的处理的每次迭代都依赖于它发生的顺序,事情可能会变得很奇怪——ajax 调用可能会以任何顺序返回。当您绘制路线时,很可能就是这种情况。

如果是这样,您可以将代码分成两个阶段 - 加载阶段和处理阶段。在加载阶段运行所有回调,然后当您将所有数据移至处理阶段并将标记放置在地图上时。您可以将数据存储在对象数组中。

有几种方法可以检测加载阶段的结束。一个是计数器,每次进行 ajax 调用时递增,每次成功时递减。您可以使用相同的计数器创建加载进度条。

如果任何调用失败,您也可以向用户显示一条消息,并带有重新启动该过程的链接。(通常这会重新加载整个页面,但您可以重新启动加载阶段。)

HTH。如果您需要进一步的帮助,请务必大声喊叫。

于 2012-12-17T23:25:55.453 回答