附加事件处理程序回调如:
$("someSelector").on('click',callBackHandler);
function callBackHandler(){
//Some code
$.ajax({
//Ajax call with success methods
})
}
我的成功方法是操纵一些对象属性。由于涉及ajax,它不会等待完成,下一个事件处理将开始。如何确保下次单击事件处理仅在先前处理完成时启动。
无法想到在此使用延迟手动的方法,因为我在for循环的某些条件的基础上手动触发事件(不是一种干净的编码风格,但在特定用例中没有其他选项)。
$('someSelector').trigger('click');
答案 0 :(得分:1)
$("someSelector").on('click', function(event) {
event.preventDefault();
var urAjax = $.ajax({
// Ajax Call here...
});
urAjax.always(function(response) {
$.when( callBackHandler() ).done(function() {
// Handle your ajax response in here!
});
});
});
function callBackHandler() {
// Do Stuff
}
callBackHandler
函数将会触发,完成后,你的ajax响应会在此之后直接触发。这允许在callBackHandler
函数运行时加载ajax,但在函数完成之前不会触发响应!希望我能理解你在这里要求的东西。
您可以在此处看到一个示例jsfiddle:https://jsfiddle.net/e39oyk8q/11/
尝试在AJAX请求完成之前多次单击“提交”按钮,您会注意到它将在“提交”按钮上一遍又一遍地循环您提供的总点击次数。您可以通过警告框弹出的次数看到这一点,并且在每次调用callBackHandler
函数期间,它会向len添加100(在页面上输出)。所以,我确实相信这就是你要求的。
当然,你仍然可以使用:$('someSelector').trigger('click');
修改强>
另一种方法是返回一个json对象,该对象可以在ajax调用中使用,或者在click事件中的任何位置使用,如下所示:
$("someSelector").on('click', function(event) {
event.preventDefault();
var myfunc = callBackHandler();
var urAjax = $.ajax({
type: 'POST',
url: myfunc['url'],
data: myfunc['data']
});
urAjax.always(function(response) {
$.when( myfunc ).done(function() {
console.log(myfunc['time']);
// Handle your ajax response in here!
});
});
});
function callBackHandler() {
var timestamp = new Date().getTime();
return { url: 'my_ajax_post_url', data: {data1: 'testing', data2: 'testing2'}, time: timestamp }
}
这里的小提琴示例:https://jsfiddle.net/e39oyk8q/15/
答案 1 :(得分:0)
您可以删除函数调用时的绑定,并在ajax为done()
时再次绑定。
function callBackHandler(){
$("someSelector").off('click');
//Some code
$.ajax({
//Ajax call with success methods
}).done(function(){
$("someSelector").on('click',callBackHandler);
})
}
答案 2 :(得分:0)
var requestDataButton = document.querySelector('.js-request-data');
var displayDataBox = document.querySelector('.js-display-data');
var displayOperationsBox = document.querySelector('.js-display-operations');
var displayNumberOfRequestsToDo = document.querySelector('.js-display-number-of-requests-to-do');
var isAjaxCallInProgress = false;
var numberOfAjaxRequestsToDo = 0;
var requestUrl = 'http://jsonplaceholder.typicode.com/photos';
requestDataButton.addEventListener('click', handleClick);
function handleClick() {
displayNumberOfRequestsToDo.innerText = numberOfAjaxRequestsToDo;
numberOfAjaxRequestsToDo++;
if(!isAjaxCallInProgress) {
isAjaxCallInProgress = true;
requestData();
}
}
function handleResponse(data) {
displayData(data);
displayOperationsBox.innerHTML = displayOperationsBox.innerHTML + 'request handled <br>';
numberOfAjaxRequestsToDo--;
displayNumberOfRequestsToDo.innerText = numberOfAjaxRequestsToDo;
if(numberOfAjaxRequestsToDo) {
requestData();
} else {
isAjaxCallInProgress = false;
}
}
function displayData(data) {
displayDataBox.textContent = displayDataBox.textContent + JSON.stringify(data[0]);
}
function requestData() {
var request = new XMLHttpRequest();
request.open('GET', requestUrl, true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
var data = JSON.parse(this.response);
handleResponse(data);
} else {
// on error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
displayOperationsBox.innerHTML = displayOperationsBox.innerHTML + 'request sent <br>';
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="js-request-data">Request Data</button>
<div>
<h2>Requests wainting in a queue to be sent:
<span class="js-display-number-of-requests-to-do">
0
</span>
</h2>
</div>
<div>
<h2>Operations:</h2>
<div class="js-display-operations"></div>
</div>
<div>
<h2>Response Data:</h2>
<div class="js-display-data"></div>
</div>
&#13;
修改强>
这里是一个实用函数,它接受与$ .ajax类似的参数,然后返回一个增强的$ .ajax函数,该函数会密切关注其先前的调用,并在调度另一个ajax调用之前等待所有先前的请求完成(顺序解雇):
function sequentialize(requestData, responseHandler) {
let inProgress = false;
let deferredRequests = 0;
const makeRequest = () => {
$.ajax(requestData).then(processManager);
};
const processManager = (data) => {
responseHandler(data);
if (deferredRequests) {
deferredRequests--;
makeRequest();
} else {
inProgress = false;
}
};
return function () {
if (!inProgress) {
inProgress = true;
makeRequest();
} else {
deferredRequests++;
}
};
}