Javascript 多个ajax异步不正常,需要同步行为

Javascript 多个ajax异步不正常,需要同步行为,javascript,jquery,html,ajax,api,Javascript,Jquery,Html,Ajax,Api,对不起,我的第一语言不是英语。我不确定我是否正确地解释了我的问题 我的代码就像一个主函数,有两个ajax函数使用ajax函数来获取foursquare API main(){ ajax1(); ajax2(); all other codes } ajax2函数必须从ajax1获取结果作为输入,然后返回结果。结果被推送到全局数组中 所有其他代码都应该在两个ajax函数完成后处理。我试过ASIN:错误,但不起作用。我的html文件包括如下最新jquery &l

对不起,我的第一语言不是英语。我不确定我是否正确地解释了我的问题

我的代码就像一个主函数,有两个ajax函数使用ajax函数来获取foursquare API

main(){

      ajax1();

      ajax2();

   all other codes
}
ajax2函数必须从ajax1获取结果作为输入,然后返回结果。结果被推送到全局数组中

所有其他代码都应该在两个ajax函数完成后处理。我试过ASIN:错误,但不起作用。我的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是全局数组


因此,当函数正常工作时,第一个问题是。alerttest1在完成第一个JSON后工作。但是,传递函数内的for循环将中断when函数。我怎样才能解决这个问题。请帮帮我。如果您能给我提供任何相关信息,我将不胜感激。谢谢

这将在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);
}
当您使用$ajax返回第一个用户的承诺时

因此,您可以这样组织代码:

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

return $.ajax();
这将返回一个承诺,您可以将其链接。 你把你想做的事情放到另一个方法中,然后在最后一个方法中调用它。

非阻塞示例 您应该使用非阻塞代码。您可以关闭async-off-async:false,但这可以通过使用回调函数在非阻塞manor中轻松实现

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
        }
      });
    }
  })
}
这是一种非阻塞方法,将函数嵌套在成功回调函数中。将ajax2嵌套在ajax1的成功回调中,以确保在ajax1返回之前不会执行ajax2,并将所有其他代码嵌套在ajax2的成功回调中,以确保在ajax2返回之前不会执行这些代码

阻塞示例 如果您一定要不惜一切代价避免,您可以禁用async,这将阻止所有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;
}
我再次强调,不要禁用会导致代码阻塞并且是错误代码的异步。如果由于某种原因,您绝对100%必须这样做,那么这是可以做到的,但是您应该尝试学习如何像第一个示例那样使用回调编写非阻塞代码

社交网络示例 现在,我将执行一个ajax调用示例以获取朋友ID数组,然后执行一系列ajax调用以获取每个朋友的个人资料。第一个ajax将获取列表,第二个ajax将获取它们的概要文件并存储,然后在检索到所有概要文件后,可以运行其他一些代码

对于本例,urlhttps://api.site.com/{userID}/friends/检索具有特定用户的好友ID列表的对象,以及https://api.site.com/{userID}/profile/获取任何用户配置文件。 显然,这是一个简化的api,因为您可能需要首先使用apikey建立一个连接,并为此连接获取一个令牌,该令牌可能需要传递给api URI,但我认为它仍然应该说明这一点

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
})

这个例子是非阻塞的,如果这个例子是以阻塞的方式完成的,那么我们将请求1个friends profile,然后等待它的响应,然后请求next并等待,依此类推。如果我们有数百个朋友,您可以看到所有ajax调用都需要很长时间才能完成。在这个非阻塞的示例中,所有对概要文件的请求都是在1ms内同时发出的,然后可以在几乎完全相同的时间返回,并且使用一个计数器来查看我们是否已从所有请求中获得响应。这比使用阻塞方法快得多,尤其是如果你有很多朋友的话。

循环i=0;i<3;传输中的i++{return…;}只会执行一次您只需要在ajax1的回调成功中调用ajax2。Thx,您能否帮助我在将所有photourl推入photourl数组后处理所有其他代码。我尝试在ajax1的回调成功中调用ajax2。不过,在运行ajax2回调成功之前,程序将运行所有其他代码。您好,谢谢您的回复。我以前试过这个,但遇到了一个问题。这可以在ajax1之后正确执行ajax2,但在ajax2传输完成后如何运行其他代码?$;我在firstjson的回调成功中添加了alerttest1,在传输的回调成功中添加了alerttest2。test3将在test2之前显示。所以所有其他代码在ajax2传输之前仍然运行。嗨,我使用callba尝试您的解决方案
ck函数和它的工作原理。然而,我的第二个ajax函数传输是在for循环中进行的。我需要处理所有其他代码后,循环完成,这样我就可以得到所有的photourl。你能告诉我如何解决这个问题吗?第二个ajax的url每次都需要被PhotoJson[i]更改,所以它需要位于for环孔内,然后你需要设置一个返回计数器。每次第二个ajax返回时,计数器都会上升,并与数组的长度进行比较。当计数等于其他代码调用的长度时,请参见我的更新,以获取循环中的ajax调用示例,并在所有ajax调用完成后执行回调