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

multiple ajax async not in order and need synchronous behavior

本文关键字:同步 排列 异步 ajax 顺序 多个      更新时间:2023-09-26

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

我的代码就像一个主函数有两个ajax函数(使用ajax函数得到四方API(

main(){
      ajax1();
      ajax2();
   all other codes
}

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

所有其他代码应在两个 Ajax 函数完成后处理。我尝试了 asyn:假,但它不起作用。我的 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!!!!
         });
    });

照片网址是全局数组

所以第一个"when"函数工作正常。 alert("test1"( 在 firstjson 完成后工作。但是,传递函数中的 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();

这将返回您链接的承诺。你把你想做的事情放在另一个方法中,所以你在最后一个"then"中调用它。

非阻塞示例

您应该使用非阻塞代码。你可以关闭异步(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
        }
      });
    }
  })
}

这将是非阻塞方法,将您的函数嵌套在"成功"回调函数中。将

ajax2 嵌套在 ajax1 的"成功"回调中,以确保在 ajax1 返回之前不会执行 ajax2,并将您的"所有其他代码"嵌套在 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;
}

我再次强调,尽量不要禁用异步,这会导致您的代码阻塞并且是坏代码。如果您出于某种原因绝对 100% 必须这样做,但您应该尝试学习如何像第一个示例一样使用回调编写非阻塞代码。

<小时 />

社交网络示例

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

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

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 个朋友的个人资料,然后等待它的响应,然后请求下一个并等待,依此类推。如果我们有数百个朋友,你可以看到完成所有 ajax 调用需要很长时间。在这个非阻塞的例子中,所有对配置文件的请求都是同时发出的(在 1 毫秒内(,然后几乎可以在同一时间返回,并使用计数器来查看我们是否从所有请求中获得了响应。这比使用阻止方法要快得多,特别是如果您有很多朋友。