Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
jQuery中的多个嵌套AJAX调用:如何在不返回同步的情况下正确执行?_Ajax_Facebook Graph Api_Asynchronous_Synchronous_Ajax Request - Fatal编程技术网

jQuery中的多个嵌套AJAX调用:如何在不返回同步的情况下正确执行?

jQuery中的多个嵌套AJAX调用:如何在不返回同步的情况下正确执行?,ajax,facebook-graph-api,asynchronous,synchronous,ajax-request,Ajax,Facebook Graph Api,Asynchronous,Synchronous,Ajax Request,我知道,这里已经有很多关于AJAX和同步性的问题,但不知何故,我没有找到正确的答案。请温柔一点,我是一个傻瓜,所以,这可能是一个复制品。尽管如此,即使暗示这一点也可能帮助我和其他人找到合适的答案 功能 $.fn.facebookEvents = function(options){ var fbEvents = 'https://graph.facebook.com/'+options.id+'/events/?access_token='+options.access_token+'&

我知道,这里已经有很多关于AJAX和同步性的问题,但不知何故,我没有找到正确的答案。请温柔一点,我是一个傻瓜,所以,这可能是一个复制品。尽管如此,即使暗示这一点也可能帮助我和其他人找到合适的答案

功能

$.fn.facebookEvents = function(options){
    var fbEvents = 'https://graph.facebook.com/'+options.id+'/events/?access_token='+options.access_token+'&since=now&limit=500';
    var events = [];

    $.when($.getJSON(fbEvents)).then(function(json){

        $.each(json.data, function(){
            $.getJSON('https://graph.facebook.com/'+this.id+'/?access_token='+options.access_token, function(jsonData){ 
                events.push(jsonData);
                console.log(events);            // here array "events" is filled successively
            });
                console.log(events);            // here array "events" remains empty
        });

    }).done(function(){

        $("#fb_data_live").html(
            $("#fb_events").render(events)
        );

    });
};
这个函数中发生的是一个AJAX调用(通过jQuerys getJSON速记),用于Facebook页面的事件列表。这将返回代表每个日期的JSON对象列表。一个对象作为响应的示例:

{ 
  "end_time": "2017-03-16T23:00:00+0100",
  "location": "Yuca K\u00f6ln",
  "name": "K\u00f6rner // G\u00e4nsehaut Tour 2017 // K\u00f6ln",
  "start_time": "2017-03-16T20:00:00+0100",
  "timezone": "Europe/Berlin",
  "id": "985939951529300" 
},
不幸的是,这些缺少我们需要的细节。它们是隐藏的(嵌套的),在生成第二个getJSON(函数中的第8行)后,可以使用每个对象的单个“id”找到它们。现在Facebook回复:

{
   "description": "http://www.eventim.de/koerner\nTickets ab sofort exklusiv auf eventim.de und ab MI 07.09. \u00fcberall wo es Tickets gibt sowie auf contrapromotion.com.",
   "end_time": "2017-03-16T23:00:00+0100",
   "is_date_only": false,
   "location": "Yuca K\u00f6ln",
   "name": "K\u00f6rner // G\u00e4nsehaut Tour 2017 // K\u00f6ln",
   "owner": {
      "name": "K\u00f6rner",
      "category": "Musician/Band",
      "id": "366592010215263"
   },
   "privacy": "OPEN",
   "start_time": "2017-03-16T20:00:00+0100",
   "timezone": "Europe/Berlin",
   "updated_time": "2016-09-28T10:31:47+0000",
   "venue": {
      "name": "Yuca K\u00f6ln"
   },
   "id": "985939951529300"
}
瞧,我在找的细节。在进行第二次(嵌套的)AJAX调用之后,我将JSON数据推送到数组“events”(第12行)中

问题

这将用每一次迭代填充数组。不过,请看两个“console.logs”。第一个返回填充数组,第二个返回空数组。。。如果AJAX调用是同步进行的(这不是应该的方式),例如通过添加
$.ajaxSetup({async:false})在函数之前,它可以正常工作。数组已填充并可以渲染(第18行)

问题

如何解释这种行为,如何正确执行此功能?我知道,一定有办法使用延迟和承诺?我想我做到了,通过使用。何时。然后。完成。。。显然我错了

致以最良好的祝愿,
朱利叶斯显然你对承诺一无所知。我想我会用其他的方法,但通过承诺,你可以做到以下几点:

$.fn.facebookEvents = function(options){
    var fbEvents = 'https://graph.facebook.com/'+options.id+'/events/?access_token='+options.access_token+'&since=now&limit=500';
    var events = [];
    var deferred=$.Deferred();
    var promises=[];
    var done=false;

    $.when(deferred).then(function(events) {
      console.log(events);
    });

    $.getJSON(fbEvents).done(function(json){
        $.each(json.data, function(){
            promises.push($.getJSON('https://graph.facebook.com/'+this.id+'/?access_token='+options.access_token).done(function(jsonData){ 
                events.push(jsonData);
                var completed=promises.filter(function(element) { return element.state=='pending' }).length==0;
                if(done&&completed) {
                  deferred.resolve(events);
                }
            }));
        });
        done=true;
    });
};

谢谢你的回答。为了完整起见,我提出了另一种解决方案

$.fn.facebookEvents = function(options){
    var fbEvents = 'https://graph.facebook.com/'+options.id+'/events/?access_token='+options.access_token+'&since=now&limit=500';
    var events = [];
    var eventsData = [];
    var i;

    // first call
    function A() {
        return $.getJSON(fbEvents).then(function(json){
            events.push(json);
            i = events[0].data.length;
        });
    };

    // second call for objects details
    function B(resultFromA) {
        $.each(events[0].data, function(){
            $.getJSON('https://graph.facebook.com/'+this.id+'/?access_token='+options.access_token, function(jsonData){                 
                eventsData.push(jsonData);
                i--;

                if ( i == 0 ){
                    output(eventsData);
                };
            });
        });
    };

    A().then(B);

    function output() {
        //render here
    };

};