繁体   English   中英

等待来自外部API的数据

[英]Wait for data from external API

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

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

在浏览器中,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条件将失败并且该函数将静默返回。 当第二个结果出现时,两个变量都将被设置。 现在,如果满足条件,则处理代码将运行。

有1001种方法可以给谚语的猫换皮,但希望它们能使您有效地使用回调。

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

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

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

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

HTH。 如果您需要进一步的帮助,一定要喊。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM