无法使用异步javascript进行同步

时间:2015-10-26 15:38:25

标签: javascript jquery ajax

我在自己的RSS阅读器中使用JS,JQuery和PHP来提供数据作为JSON。我基本上做的是对我的服务器进行异步调用以获取帖子的JSON,然后成功'成功'我使用' $。每个'解析它们。并使用JQuery加载DOM中的内容。 所有这些操作都是异步的,但是现在我需要按照一定的顺序调用它们,当完成everithin时,然后调用一个函数来处理数据。 为了给你一些关于我的任务的背景知识,我正在做的是对一小部分RSS源进行查询以获得最新的帖子。使用它们我会串起一个字符串,并将此字符串传递给文本转语音服务。 我设法使用10秒的任意setTimeout值使其工作,但我的目标是在处理完所有源时调用该函数。

这是我的解析器的基本版本:

function urgent_posts(url) {
  $.ajax({
    //the location of my server
    url: 'myPostServer.php?url=' + encodeURIComponent(url),
    dataType: 'json',
    success: function(data) {
      //do this for each entry in the feed
      $.each(data.feed.entries, function(key, value) {
        //validate the date to get just the latest post
        if (is_urgent(value.publishedDate)) {
          //if condition is met save the title
          save_urgent_post_title(value.title);
        }
      });
    }
  });
}

我做了什么让它发挥作用'如下:

$('#test_button').on('click',function(){

  urgent_posts(source_1);
  urgent_posts(source_2);
  urgent_posts(source_3);
  //and so on...
  urgent_posts(source_n);

  setTimeout(function(){
    text_to_speech(get_urgent_post_string);
  },10000);

});

我尝试了没有结果来使用延迟对象y JQuery,如下所示:

function urgent_posts(url) {
  var deferred = $.Deferred();
  $.ajax({
    //the location of my server
    url: 'myPostServer.php?url=' + encodeURIComponent(url),
    dataType: 'json',
    success: function(data) {
      //do this for each entry in the feed
      $.each(data.feed.entries, function(key, value) {
        //validate the date to get just the latest post
        if (is_urgent(value.publishedDate)) {
          //if condition is met save the title
          save_urgent_post_title(value.title);
        }
      });
    }
  });
  return deferred.promise();
}

将所有内容链接在一起:

$('#test_button').on('click',function(){

  urgent_posts(source_1)
  .then(urgent_posts(source_2))
  .then(urgent_posts(source_3))
  .then(function(){
    text_to_speech(get_urgent_post_string);
  });

});

我要提出您的意见和建议。

2 个答案:

答案 0 :(得分:3)

首先,永远不会解析您的延迟对象。你必须在某处添加deferred.resolve()。就在$.each循环看起来像个好地方之后。

其次,$.ajax已经返回一个承诺。所以你可以这样写:

return $.ajax({
    //the location of my server
    url: 'myPostServer.php?url=' + encodeURIComponent(url),
    dataType: 'json',
    success: function(data) {
      //do this for each entry in the feed
      $.each(data.feed.entries, function(key, value) {
        //validate the date to get just the latest post
        if (is_urgent(value.publishedDate)) {
          //if condition is met save the title
          save_urgent_post_title(value.title);
        }
      });
    }
  });

答案 1 :(得分:0)

我设法使用这篇文章来解决问题:link

重构的代码现在看起来像这样:

function urgent_posts_feed_1(callback) {
  return $.ajax({
    //the location of my server
    url: 'myPostServer.php?url=' + encodeURIComponent(feed_1),
    dataType: 'json',
    success: function(data) {
      //do this for each entry in the feed
      $.each(data.feed.entries, function(key, value) {
        //validate the date to get just the latest post
        if (is_urgent(value.publishedDate)) {
          //if condition is met save the title
          save_urgent_post_title(value.title);
        }
      });
    }
  });
}

我重复一遍(我知道这样做并不酷)并且手动设置以下函数来设置网址:

urgent_posts_feed_2 urgent_posts_feed_3 urgent_posts_feed_4 ... urgent_posts_feed_n

最后......

urgent_post_feed_1()
.then(urgent_post_feed_2)
.then(urgent_post_feed_3)
//...
.then(urgent_post_feed_n)
.then(function(){
    text_to_speech(get_urgent_post_string);
});

这种方式就像魅力一样。现在我必须弄清楚如何将参数传递给函数而不干扰回调。