$('.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...
}
});
虽然你应该发布一个伪代码,你的ajax请求被称为更精确...
0
试试这种方式 . 在java脚本函数中创建一个循环,等待ajax调用完成 .
function getLabelById(id)
{
var label = '';
var done = false;
$.ajax({
cache: false,
url: "YourMvcActionUrl",
type: "GET",
dataType: "json",
async: false,
error: function (result) {
label='undefined';
done = true;
},
success: function (result) {
label = result.Message;
done = true;
}
});
//A loop to check done if ajax call is done.
while (!done)
{
setTimeout(function(){ },500); // take a sleep.
}
return label;
}
//multiple ajax calls above
var callback = function () {
if ($.active !== 0) {
setTimeout(callback, '500');
return;
}
//whatever you need to do here
//...
};
callback();
let urlCreator = window.URL || window.webkitURL;
// Helper function for making ajax requests
let fetch = function(url) {
return $.ajax({
type: "get",
xhrFields: {
responseType: "blob"
},
url: url,
});
};
// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));
// Use the spread operator to wait for all requests
$.when(...files).then(function() {
// If we have multiple urls, then loop through
if(urls.length > 1) {
// Create image urls and tags for each result
Array.from(arguments).forEach(data => {
let imageUrl = urlCreator.createObjectURL(data[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
});
}
else {
// Create image source and tag for result
let imageUrl = urlCreator.createObjectURL(arguments[0]);
let img = `<img src=${imageUrl}>`;
$("#image_container").append(img);
}
});
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;
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four ajax requests resolve.
// a1, a2, a3 and a4 are lists of length 3 containing the response text,
// status, and jqXHR object for each of the four ajax calls respectively.
});
function ajax1() {
// NOTE: This function must return the value
// from calling the $.ajax() method.
return $.ajax({
url: "someUrl",
dataType: "json",
data: yourJsonData,
...
});
}
// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
counter++;
if( counter >= ajaxCalls ) {
// When all ajax calls has been done
// Do something like hide waiting images, or any else function call
$('*').css('cursor', 'auto');
}
};
var loadPersons = function() {
// Show waiting image, or something else
$('*').css('cursor', 'wait');
var url = global.ctx + '/loadPersons';
$.getJSON(url, function(data) {
// Fun things
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCountries = function() {
// Do things
var url = global.ctx + '/loadCountries';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCities = function() {
// Do things
var url = global.ctx + '/loadCities';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
$(document).ready(function(){
loadPersons();
loadCountries();
loadCities();
});
function untilAjax(ajaxObjs, fn) {
if (!ajaxObjs || !fn) {
return;
}
var ajaxCount = ajaxObjs.length,
succ = null;
for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
succ = ajaxObjs[i]['success'];
ajaxObjs[i]['success'] = function(data) { //modified success handler
if (succ) {
succ(data);
}
ajaxCount--;
if (ajaxCount == 0) {
fn(); //modify statement suitably if you want 'this' keyword to refer to another object
}
};
$.ajax(ajaxObjs[i]); //make ajax call
succ = null;
};
示例: doSomething 函数使用 untilAjax .
function doSomething() {
// variable declarations
untilAjax([{
url: 'url2',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url1',
dataType: 'json',
success: function(data) {
//do something with success data
}
}, {
url: 'url2',
dataType: 'json',
success: function(response) {
//do something with success data
}
}], function() {
// logic after all the calls are completed.
});
}
函数 triggerNowOrOnLoaded 没有't care if the data has been already loaded or we'还在等待它
将它插入现有代码非常容易
$(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);
});
}
runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function
21 回答
我发现good answer是gnarf我的自我,这正是我想要的:)
jQuery ajaxQueue
然后你可以像这样添加一个ajax请求到队列:
$.when
对我不起作用,callback(x)
而不是return x
如此处所述:https://stackoverflow.com/a/13455253/10357604我遇到了这个问题并创建了一个通用的插件jquery_counter来解决它:https://bitbucket.org/stxnext/jquery_counter/
你也可以使用async.js .
我认为它比$ .when更好,因为你可以合并各种不支持promises的异步调用,如超时,SqlLite调用等,而不仅仅是ajax请求 .
javascript是基于事件的,所以你永远不应该等待,而是设置钩子/回调
您可以只使用jquery.ajax的成功/完整方法
或者您可以使用.ajaxComplete:
虽然你应该发布一个伪代码,你的ajax请求被称为更精确...
试试这种方式 . 在java脚本函数中创建一个循环,等待ajax调用完成 .
使用
ajaxStop
事件 .例如,假设您在获取100个ajax请求时有一条 loading ... 消息,并且您希望在加载后隐藏该消息 .
来自jQuery doc:
请注意,它将等待在该页面上完成的所有ajax请求 .
jQuery允许您指定是否希望ajax请求是异步的 . 您可以简单地使ajax请求同步,然后其他代码在返回之前不会执行 .
例如:
如果你需要简单的东西;一次完成回调
为了扩展Alex的答案,我有一个带有可变参数和承诺的例子 . 我想通过ajax加载图像,并在加载后在页面上显示它们 .
为此,我使用了以下内容:
已更新,可用于单个或多个网址:https://jsfiddle.net/euypj5w9/
NOTE: 以上答案使用的是撰写本答案时不存在的功能 . 我建议使用
jQuery.when()
而不是这些方法,但我是出于历史目的而离开答案 .你可能会使用一个简单的计数信号量,虽然你如何实现它将取决于你的代码 . 一个简单的例子就是......
如果您希望它像{async:false}那样运行,但您不想锁定浏览器,则可以使用jQuery队列完成相同的操作 .
当所有ajax加载完成时,我正在使用大小检查
Alex给出的解决方案很好 . 相同的概念,但使用它有点不同的方式(当预先不知道呼叫的数量)
http://garbageoverflow.blogspot.com/2014/02/wait-for-n-or-multiple-or-unknown.html
jQuery现在为此目的定义了when function .
它接受任意数量的Deferred对象作为参数,并在所有这些对象解析时执行一个函数 .
这意味着,如果你想发起(例如)四个ajax请求,然后在完成后执行一个动作,你可以这样做:
在我看来,它使得语法清晰明确,并避免涉及任何全局变量,如ajaxStart和ajaxStop,这些变量可能会在页面开发时产生不必要的副作用 .
如果你事先不知道需要等待多少个ajax参数(即你想使用可变数量的参数),它仍然可以完成,但只是有点棘手 . 见Pass in an array of Deferreds to $.when()(也许jQuery .when troubleshooting with variable number of arguments) .
如果你需要更深入地控制ajax脚本等的失败模式,你可以保存
.when()
返回的对象 - 它是一个包含所有原始ajax查询的jQuery Promise对象 . 您可以在其上调用.then()
或.fail()
以添加详细的成功/失败处理程序 .一个小的解决方法是这样的:
希望可以有用......
在@BBonifield答案的基础上,我编写了一个实用程序函数,以便信号量逻辑不会在所有的ajax调用中传播 .
untilAjax
是实用程序函数,它在完成所有ajaxCalls时调用回调函数 .ajaxObjs
是ajax设置对象[http://api.jquery.com/jQuery.ajax/]
的数组 .fn
是回调函数示例:
doSomething
函数使用untilAjax
.如果你从头开始,我强烈推荐使用$.when() .
即使这个问题有超过百万的答案,我仍然没有找到任何有用的案例 . 假设您必须处理现有的代码库,已经进行了一些ajax调用,并且不想引入promises的复杂性和/或重做整个事情 .
我们可以轻松利用jQuery
.data
,.on
和.trigger
函数,这些函数已成为其中的一部分jQuery永远 .Codepen
关于我的解决方案的好处是:
显然回调究竟取决于什么
函数
triggerNowOrOnLoaded
没有't care if the data has been already loaded or we'还在等待它将它插入现有代码非常容易
看看我的解决方案:
1.将此函数(和变量)插入到您的javascript文件中:
2.使用您的请求创建一个数组,如下所示:
3.创建回调函数:
4.使用参数调用runFunctionQueue函数:
如果你想等到文档中的所有ajax请求都完成,无论它们有多少,只需这样使用$.ajaxStop事件:
在这种情况下,无需猜测将来可能完成的应用程序中有多少请求 . 在某些情况下,ajax请求可以是函数内部逻辑的一部分,这可能非常复杂(例如调用其他函数),在这种情况下,您可能不会等到所述函数完成其整个逻辑而不是仅等待
ajax
部分完成 .$.ajaxStop此处也可以绑定到您认为可能被
ajax
修改的任何HTML
节点 .再次,这个处理程序的目的是知道什么时候没有清除或重置某些东西 active
ajax
.附:如果您不介意使用ES6语法,则可以将
Promise.all
用于已知的ajax
方法 . 例:这里有一个有趣的观点是,它适用于
Promises
和$.ajax
请求 . 这是jsFiddle展示了最后一个 .我找到了简单的方法,它使用
shift()
我的解决方案如下
工作得很好 . 我已经尝试了很多不同的方法,但我发现这是最简单和最可重用的方法 . 希望能帮助到你