Reputation: 157
Consider the following setting:
My code:
// PageA.html
<script>
$(document).ready(function () {
$("#callAjax").click(function () {
$(".loading").show();
$.ajax({
type: "GET",
url: "PageB.html"
}).done(function() {
$(".loading").hide();
});
});
});
</script>
// PageB.html
<script type="text/javascript">
$(document).ready(function() {
var urls = [
"url1.php",
"url2.php",
:
:
];
for (var i = 0; i < urls.length; i++) {
$.ajax({
type: "GET",
url: urls[i]
});
}
window.location = "{{ URL::to('/') }}";
});
</script>
The result of this setup happens such that there is no updating and the refresh hijacks all the other functions. I guess that is because the AJAX in PageB.html has not yet completed.
I'm doing this to decrease the computation time by PHP and for performance.
Is there any way to get this to work?
UPDATE: I found out that I was wrong about the refresh hijacking. There is no refresh. There is no update. It's just the AJAX call by PageA.html. PageB.html's AJAX calls are not executed.
Upvotes: 4
Views: 155
Reputation: 76784
Just some extra info:
Ajax Callbacks
If you're relying on Ajax calls to run before executing any other code, you should look at Ajax Callbacks
Although Ajax can run synchronously, this actually freezes the browser, causing all sorts of problems. The way around this is to work the code around the Ajax calls, not the other way around
Reason why I'm writing this is because we had a problem where we had to rely on an Ajax response in order to load a modal form. Problem was we didn't want to do it synchronously, and considering Ajax (Asynchronous Javascript And XML) is asynchronous by default, we had to get it working another way:
#PageA.html
$(document).ready(function () {
$("#callAjax").click(function () {
$(".loading").show();
fetch_data(function(data){
//success
}, function(data){
//error
}, function(data) {
$(".loading").hide();
});
});
});
function fetch_data(success, error, done) {
$.ajax({
type: "GET",
url: "PageB.html"
success: function(data) { success(data); },
error: function(data) { error(data); }
});
};
Your Code
The callback stuff will definitely work for PageA
, so I guess the important part is making it happen for PageB
. Maybe this could work:
#PageA.html
$(document).ready(function () {
$("#callAjax").click(function () {
$(".loading").show();
fetch_data(function(data){
//success
}, function(data){
//error
}, function(data) {
$(".loading").hide();
});
});
});
function fetch_data(success, error, done) {
$.ajax({
type: "GET",
url: "PageB.html"
success: function(data) { success(data); },
error: function(data) { error(data); }
});
};
#PageB.html
$(document).ready(function() {
var urls = [
"url1.php",
"url2.php",
:
:
];
for (var i = 0; i < urls.length; i++) {
fetch_data(urls[i] function(data) {
//success
}, function(data) {
//error
});
}
window.location = "{{ URL::to('/') }}";
});
function fetch_data(url, success, error) {
$.ajax({
type: "GET",
url: url,
success: function(data) { success(data) },
error: function(data) { error(data) }
});
}
This could be super memory intensive, but it's what I would start with. I doubt the PageB stuff is going to work out of the box, but hopefully the callback idea will be of help
Upvotes: 1
Reputation: 1701
This scenario must be handled through synchronous way.
your refresh()
code wont know if ajax was finished as you are opening request asynchronously. That will immediately return and you never know when would all ajax requests are returned. They are like threads, and your refresh() page code too would be a thread like thing. they wont follow an order if you don't call these methods synchronously.
One solution to this will be to increment a counter on returning(callback) of each ajax call, and if any callback finds your counter to be the number of your (ajax) methods, then do a refresh of the page. (window.location = "{{ URL::to('/') }}";
).
Other solution, as I think would be to use synchronous calls.
Upvotes: 0
Reputation: 1758
You might want to learn about
$.ajaxStart()
(http://api.jquery.com/ajaxStart/)
$.ajaxStop()
(http://api.jquery.com/ajaxStop/).
It should allow you to know more about your ajax requests.
You can start all your ajax calls, then wait for ajaxStop()
to know if all your requests are over and do window.location = "{{ URL::to('/') }}";
Hope it helps.
EDIT
You should place the pageB's js into pageA, or it won't be executed
// PageA.html
<script>
function doPageB() {
var urls = [
"url1.php",
"url2.php",
:
:
];
for (var i = 0; i < urls.length; i++) {
$.ajax({
type: "GET",
url: urls[i]
});
}
window.location = "{{ URL::to('/') }}";
});
}
$(document).ready(function () {
$("#callAjax").click(function () {
$(".loading").show();
$.ajax({
type: "GET",
url: "PageB.html"
}).done(function() {
$(".loading").hide();
doPageB();
});
});
});
</script>
Ajax loaded content shouldn't have javascript in it. Javascript is interpreted only on window load, not ajax calls.
So you need to place pageB's javascript into your main page, and call it when your pageB is loaded (see edit's code sample).
Also, your ajax calls are asynchronous, so javascript code will continue to execute even if ajax haven't finished and in your case reload the page before ajax calls are over.
Two options to handle this : make ajax calls synchronous, or use ajaxStop to know when every ajax calls are over and then reload the page with window.location = url.
I think what you're trying to do is useless :
You load a page, load more content with ajax, then reload the page. So the ajax you've done will just be canceled.
I think you need to learn more about ajax do understund what's wrong
Upvotes: 0
Reputation: 74738
You can try this way:
// PageA.html
<script>
$(document).ready(function () {
$("#callAjax").click(function () {
$(".loading").show();
$.ajax({
type: "GET",
url: "PageB.html"
}).done(function() {
$(".loading").hide();
pageBajax();
});
});
});
</script>
// PageB.html
<script type="text/javascript">
function pageBajax() {
var urls = [
"url1.php",
"url2.php",
:
:
];
for (var i = 0; i < urls.length; i++) {
$.ajax({
type: "GET",
url: urls[i]
});
}
window.location = "{{ URL::to('/') }}";
}
</script>
Upvotes: 2