ajax返回json - javascript jquery ajax




等到所有jQuery Ajax请求完成? (12)

Alex给出的解决方案工作正常。 相同的概念,但以一种不同的方式使用它(当呼叫数目未预先知道时)

http://garbageoverflow.blogspot.com/2014/02/wait-for-n-or-multiple-or-unknown.html

我如何让一个函数等到所有jQuery Ajax请求在另一个函数内完成?

简而言之,在执行下一步之前,我需要等待所有的Ajax请求完成。 但是如何?


jQuery允许你指定你是否希望ajax请求是异步的。 您可以简单地使ajax请求同步,然后其他代码将不会执行,直到它们返回。

例如:

jQuery.ajax({ 
    async: false,
    //code
});

javascript是基于事件的,所以你不应该等待 ,而是设置钩子/回调

你可能只需要使用jquery.ajax的成功/完整方法

或者你可以使用.ajaxComplete

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

尽管你应该发布一个伪代码,说明你的(s)ajax请求如何被更精确地调用。


注意:上面的答案使用了在撰写此答案时不存在的功能。 我建议使用jQuery.when()而不是这些方法,但是我为了历史目的而离开了答案。

-

你或许可以通过一个简单的计数信号来获得,尽管你如何实现它取决于你的代码。 一个简单的例子就像...

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

如果你希望像{async:false}那样操作,但你不想锁定浏览器,你可以用jQuery队列完成同样的事情。

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});

你也可以使用async.js

我认为它比$更好,因为你可以合并所有类型的异步调用,例如超时,SqlLite调用等,而不仅仅是ajax请求。


使用ajaxStop事件。

例如,假设您在获取100个Ajax请求时有加载...消息,并且您想在加载后隐藏该消息。

从jQuery $.ajaxStop

$("#loading").ajaxStop(function() {
  $(this).hide();
});

请注意,它将等待该页面上所有的Ajax请求。


如果你从头开始,我强烈建议使用$.when() 。

即使这个问题有超过百万的答案,我仍然没有发现对我的案例有用。 假设您必须处理现有的代码库,已经做出了一些Ajax调用,并且不想介绍承诺的复杂性和/或重做整个事情。

我们可以很容易地利用jQuery .data.on.trigger函数,它们一直是jQuery的一部分。

Codepen

关于我的解决方案的好东西是:

  • 很明显回调确切依赖于什么

  • triggerNowOrOnLoaded函数不关心数据是否已经被加载,或者我们仍在等待它

  • 将其插入现有代码非常容易

$(function() {

  // wait for posts to be loaded
  triggerNowOrOnLoaded("posts", function() {
    var $body = $("body");
    var posts = $body.data("posts");

    $body.append("<div>Posts: " + posts.length + "</div>");
  });


  // some ajax requests
  $.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
    $("body").data("posts", data).trigger("posts");
  });

  // doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests 
  $.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
    $("body").data("users", data).trigger("users");
  });


  // wait for both types
  triggerNowOrOnLoaded(["posts", "users"], function() {
    var $body = $("body");
    var posts = $body.data("posts");
    var users = $body.data("users");

    $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
  });

  // works even if everything has already loaded!
  setTimeout(function() {

    // triggers immediately since users have been already loaded
    triggerNowOrOnLoaded("users", function() {
      var $body = $("body");
      var users = $body.data("users");

      $body.append("<div>Delayed Users: " + users.length + "</div>");
    });

  }, 2000); // 2 seconds

});

// helper function
function triggerNowOrOnLoaded(types, callback) {
  types = $.isArray(types) ? types : [types];

  var $body = $("body");

  var waitForTypes = [];
  $.each(types, function(i, type) {

    if (typeof $body.data(type) === 'undefined') {
      waitForTypes.push(type);
    }
  });

  var isDataReady = waitForTypes.length === 0;
  if (isDataReady) {
    callback();
    return;
  }

  // wait for the last type and run this function again for the rest of the types
  var waitFor = waitForTypes.pop();
  $body.on(waitFor, function() {
    // remove event handler - we only want the stuff triggered once
    $body.off(waitFor);

    triggerNowOrOnLoaded(waitForTypes, callback);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>Hi!</body>


如果你需要简单的东西, 一次并完成回调

        //multiple ajax calls above
        var callback = function () {
            if ($.active !== 0) {
                setTimeout(callback, '500');
                return;
            }
            //whatever you need to do here
            //...
        };
        callback();

我找到简单的方法,它使用shift()

function waitReq(id)
{
  jQuery.ajax(
  {
    type: 'POST',
    url: ajaxurl,
    data:
    {
      "page": id
    },
    success: function(resp)
    {
      ...........
      // check array length if not "0" continue to use next array value
      if(ids.length)
      {
        waitReq(ids.shift()); // 2
      )
    },
    error: function(resp)
    {
      ....................
      if(ids.length)
      {
        waitReq(ids.shift());
      )
    }
  });
}

var ids = [1, 2, 3, 4, 5];    
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1

我的解决方案如下

var request;
...
'services': {
  'GetAddressBookData': function() {
    //This is the primary service that loads all addressbook records 
    request = $.ajax({
      type: "POST",
      url: "Default.aspx/GetAddressBook",
      contentType: "application/json;",
      dataType: "json"
    });
  },

  ...

  'apps': {
    'AddressBook': {
      'data': "",
      'Start': function() {
          ...services.GetAddressBookData();
          request.done(function(response) {
            trace("ajax successful");
            ..apps.AddressBook.data = response['d'];
            ...apps.AddressBook.Filter();
          });
          request.fail(function(xhr, textStatus, errorThrown) {
            trace("ajax failed - " + errorThrown);
          });

工作得很好。 我尝试了很多不同的方式来做到这一点,但我发现这是最简单和最可重用的。 希望能帮助到你



看看我的解决方案:

1.将此函数(和变量)插入到您的JavaScript文件中:

var runFunctionQueue_callback;

function runFunctionQueue(f, index, callback) {

  var next_index = index + 1

  if (callback !== undefined) runFunctionQueue_callback = callback;

  if (f[next_index] !== undefined) {
    console.log(index + ' Next function avalaible -> ' + next_index);
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      complete: function() {
        runFunctionQueue(f, next_index);
      }
    });
  } else {
    console.log(index + ' Last function');
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      async: false,
      complete: runFunctionQueue_callback
    });
  }
}

2.根据您的请求构建一个数组,如下所示:

var f = [
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}}
        ];

3.创建回调函数:

function Function_callback() {
  alert('done');
}

4.使用参数调用runFunctionQueue函数:

runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function




ajax