多个ajax异步不按顺序,需要同步行为

时间:2015-02-06 16:12:56

标签: javascript jquery html ajax api

抱歉,我的第一语言不是英语。如果我正确解释我的问题,我不确定。

我的代码就像一个main函数有两个ajax函数(使用ajax函数获取foursquare API)

main(){

      ajax1();

      ajax2();

   all other codes
}

ajax2()函数必须从ajax1()获取结果作为输入,然后返回结果(实际结果被推入全局数组)。

两个ajax函数完成后,应处理所有其他代码。我尝试了asyn:false但它没有用。我的html文件包括像这样的最新jquery

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js" ></script>

我尝试使用jquery函数$ .when()。done()函数和第一个ajax工作。但是,第二个ajax()函数在for循环中。 for循环将破坏$ .when()。done()函数的机制:

首先是ajax:在firstjson函数中 第二个ajax:传递函数

 function firstjson(tmpName,tmpLoc,PhotoJson,foursq){
    return $.ajax({
      type: 'GET',
      url: foursq,
      dataType: 'jsonp',
          success: function(json) {

              for (i = 0; i < 3; i++) {
                var resultname = json['response']['venues'][i].name;
                var resultlocation = json['response']['venues'][i].location;
                var resultlat = resultlocation.lat;
                var resultlng = resultlocation.lng;
                var tmpmarker = new google.maps.LatLng(resultlat,resultlng)

                tmpName.push(resultname);
                tmpLoc.push(tmpmarker);
                var resultid = json['response']['venues'][i].id;
                var tmpPhotoJason = 'https://api.foursquare.com/v2/venues/'+ resultid +'/photos?';
                PhotoJson.push(tmpPhotoJason);


              }


        }
   });
 }


    function transfer(PhotoJson,PhotoURL){
       for (i = 0; i < 3; i++) {

           return $.ajax({

            type: 'GET',
            url: PhotoJson[i],
            dataType: 'jsonp',
              success: function(json) {
                  resultphoto = json['response']['photos']['items'];
                  photoprefix = resultphoto[i].prefix;
                  photopresuffix = resultphoto[i].suffix;
                  photourl = photoprefix+"150x150" + photopresuffix;
                  PhotoURL.push(photourl);
              }

        });
      }
    }

    $.when(firstjson(tmpName,tmpLoc,PhotoJson,foursq)).done(function(){
            alert("test1");
          $.when(transfer(PhotoJson,PhotoURL).done(function(){
               console.log(PhotoURL);
              all other codes!!!!
         });
    });

// PhotoURL是全局数组

所以第一个&#34;当&#34;功能正常。在firstjson完成后,警报(&#34; test1&#34;)工作。但是for循环内部传递函数会破坏when函数。我该如何解决这个问题。请帮我。我将不胜感激,你可以给我任何相关的信息。感谢!!!

2 个答案:

答案 0 :(得分:0)

这将在ajax1

之后执行ajax2
function anotherMethod(){
   //Here you do all that you want to do after the last $ajax call
}
main(){
        firstjson(tmpName,tmpLoc,PhotoJson,foursq)
        .then(transfer(PhotoJson,PhotoURL))
        .then(anotherMethod);
}

当你从第一个回复承诺&#34;返回$ ajax ...&#34;

所以你要像这样组织你的代码:

在使用ajax调用的方法中,您可以像现在一样返回调用

return $.ajax();

返回您链接的承诺。 你把你想要做的事情放在另一种方法中,这样你就可以在最后一次调用它&#34;然后&#34;。

答案 1 :(得分:0)

非阻止示例

您应该使用非阻止代码。您可以关闭异步(async: false),但这可以使用回调函数在非阻塞庄园中轻松完成。

function main(){
  $.ajax({ // First ajax call (ajax1)
    url: "first/ajax/url",
    type: "GET", // POST or GET
    data: {}, // POST or GET data being passed to first URL
    success: function(x){ // Callback when request is successfully returned
      // x is your returned data
      $.ajax({ // Second ajax call (ajax2)
        url: "second/ajax/url",
        type: "GET", // POST or GET
        data: {
          thatThing: x
        }, // POST or GET data passed to second URL
        success: function(y){
          // y is your second returned data
          // all other codes that use y should be here
        }
      });
    }
  })
}

这将是非阻塞方法,将您的功能嵌套在&#34;成功&#34;回调函数。将ajax2嵌入ajax1&#34;成功&#34;回调以确保在ajax1返回之前不执行ajax2并嵌套你的所有其他代码&#34;在&#34;成功&#34;回调ajax2以确保在ajax2返回之前不会执行它们。


阻止示例

如果你绝对必须(请不惜一切代价避免),你可以禁用异步,这将阻止所有JavaScript代码执行,直到ajax返回。这可能会导致浏览器暂时冻结,直到ajax请求返回(取决于浏览器)。

function main(){
  var x = ajax1();
  var y = ajax2(x);
  window["y"] = y; // push to global as you requested but why?
  // All other codes that can now use y
}
function ajax1(){
  var x;
  $.ajax({
    url: "first/ajax/url",
    async: false,
    type: "GET", // POST or GET,
    data: {}, // POST or GET data being passed to first URL
    success: function(r){x=r}
  });
  return x;
}
function ajax2(x){
  var y;
  $.ajax({
    url: "second/ajax/url",
    async: false,
    type: "GET", // POST or GET,
    data: {
      thatThing: x
    }, // POST or GET data being passed to second URL
    success: function(r){y=r}
  });
  return y;
}

我再次强调,尽量不要禁用会导致代码阻止的异步,并且是BAD代码。如果您完全100%必须由于某种原因而不是可以完成,但您应该尝试学习如何使用回调编写非阻塞代码,如第一个示例所示。


社交网络示例

现在,我将做一个ajax调用示例,以获取您朋友ID的数组,然后进行一系列ajax调用以获取您的每个朋友个人资料。第一个ajax将获取列表,第二个将获取其配置文件并存储,然后当检索到所有配置文件时,可以运行其他一些代码。

对于此示例,网址https://api.site.com/{userID}/friends/检索具有特定用户的朋友ID列表的对象,https://api.site.com/{userID}/profile/获取任何用户个人资料。 显然这是一个简化的api,因为您可能需要首先与apikey建立连接并获取此连接的令牌,并且令牌可能需要传递给api uris但我认为它仍然应该说明这一点。 / p>

function getFriends(userID, callback){
   $.ajax({
     url: "https://api.site.com/"+userID+"/friends/",
     success: function(x){
       var counter = 0;
       var profiles = [];
       for(var i=0;i<x.friendIDs.length;i++){
         $.ajax({
           url: "https://api.site.com/"+x.friendIDs[i]+"/profile/",
           success: function(profile){
             profiles.push(profile);
             counter++;
             if(counter == x.friendIDs.length) callback(profiles);
           }
         });
       }
     }
   });
}
getFreinds("dustinpoissant", function(friends){
  // Do stuff with the 'friends' array here
})

此示例为&#34;非阻止&#34;,如果此示例是在&#34;阻止&#34;然后,我们会要求1个朋友的个人资料,然后等待其响应,然后请求下一个并等待,等等。如果我们有数百个朋友,你可以看到这需要很长时间才能完成所有ajax调用。在这个非阻塞的例子中,所有对配置文件的请求都是在同一时间(1ms内)完成的,然后几乎可以在几乎完全相同的时间返回,并使用一个计数器来查看我们是否得到了所有的响应请求。这比使用阻止方法更快,特别是如果你有很多朋友。