I am collaborating on a web project with someone who devised a series of .js scripts that act like 'plugins' in the sense that he would like them to be used on other web projects.
Most of these 'plugins' are event listener based, and they listen for clicks on elements with certain 'data' attributes. For example an element with 'data-setdata' will fire, on click, a listener in 'setdata.js':
$('body').on('click', '[data-setdata]', function(e) {
// do something
});
But one of these plugins, 'ajax.js', fires a 'post' call for AJAX-style loading of content:
$('body').on('click', '[data-ajax]', function(e) {
$.post(
//etc
);
}
});
... so of course we find ourselves in a situation in which we cannot control the order in wich 'setdata.js' and 'ajax.js' occur .
My initial thought was to get those plugins back into functions, and properly chain them using promises on a main .js
But, is there a way to delay firing the function within an event listener until a certain async action has been fulfilled? pseudocode:
$('body').on('click', '[data-setdata]', function(e) {
when( ajax call finishes ){
// do something
}
});
Thank you
You can use jQuery's ajaxComplete
event
let done = false;
$(document).on("ajaxComplete", function(event, jqxhr, settings) {
if (settings.url === "/path/to/resource" && !done) done = true;
});
$('body').on('click', '[data-setdata]', function(e) {
if (done) {
// do something
} else {
console.log(done)
}
});
As explained in this answer: https://stackoverflow.com/a/22125915/5721273 I could use a setTimeout within the plugins, to continuously poll for changes on a flag set by the ajax call completion.
function checkFlag() {
if(flag == false) {
window.setTimeout(checkFlag, 100); /* this checks the flag every 100 milliseconds*/
} else {
/* do something*/
}
}
checkFlag();
Of course this is not the proper way of doing it, which would be chaining promises.
But in the specific case-scenario that I described, in which there is a design limitation imposed by someone else, and when I already told this person about it, but still need to find a temporary workaround, this is the correct answer.
You should use ajax's complete
option, which executes when the call is completed, no matter if it is successful or not.
$.ajax({
type: "GET",
....
success: function(data) {
// do some stuff
},
error: function(data) {
// do other stuff stuff
},
complete: function(data) {
// call your other function here
}
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.