I have a rather extensive PHP page that does a lot of IP address validation for our product licensing. One of those validation routines can take 20-30 seconds, while the bulk of them happen locally and so show up very quickly. I'd like to launch that longer one in a separate jQuery GET, and display it's results while they review the results of the faster ones.
Here's the pseudo-code for the "fastchecks" that I'm working from - how/where would a "slowchecks" be launched?
$.ajax(
{
type: "GET",
dataType: "json",
url: "license/fastchecks/" + $("#ipblocks").val(),
error:function (xhr, ajaxOptions, thrownError){
alert("IP Checking Error: " + xhr.status + ": " + thrownError);
},
success: function(fastresults)
{
/* Do stuff with my fast check results while I wait for my slow check results */
}
});
Is this possible? I keep going back to a timed event, but the process itself IS a delay, so that doesn't seem to make sense to me - am I missing something?
Your code is fine as is. You don't need to use any timers or anything like that. Your "slowchecks" would be exactly the same as your "fastchecks". The keyword here is Asynchronous. That success function doesn't get called until after the ajax call completes. So whatever you wanted to do with the data you get from your ajax call, put it in your success function, and that won't actually do anything until the results are returned.
Also, you would run both Ajax calls at the same time. Each one will run it's own success function when it completes.
Related
I have an issue with a continuous Ajax to PHP loop. The code (below) works absolutely fine. However I find it will run for 2, 3, or more hours or as required.. but then have an "x minute" break where it won'T run or produce any logs... before once "again" resuming for 2, 3 or more hours.
$.ajax({
async: false,
type: "POST",
url: ajaxURL,
dataType: 'json',
data: {functionname: 'conditionTrade', arguments: [c_piars, c_timeframes, usd_amount ,stop_loss, stop_loss_min, stop_loss_max]},
// post to php and check condition
success: function (data) {
if( !('error' in data) ) {
var results = data["result"];
if (results) {
$( "#tradelog" ).load( "tradelog.html" ); // <--- produce a log
var pft = c_piars+"profitloss.txt";
$( "#profit" ).load( pft );
checkCondition();
// recursion call to this same method ie. check again
}
else {
console.log(data.error);
}
var objDiv = document.getElementById("tradelog");
objDiv.scrollTop = objDiv.scrollHeight;
}},
error: function(jqXHR, textStatus, errorThrown) {
console.log("Error[refresh]: " + textStatus);
console.log(jqXHR);
checkCondition();
// recursion call to this same method ie. check again
},
});
Please can somebody advise as to why this loop is randomly breaking, and then continuing on its own.
The loop is intended to retrieve candlestick data (approximately every 5 seconds), then perform some Technical Analysis checks, before finally.. outputing a log of the whether the TA conditions were found. The code runs fine.
However it's almost as if when I'm not physically on the browser page, then, it may randomly stop working for 15 minutes or a random time, before resuming on its own. (Hence I may get 2,3,4,5 hours of continuous checks, then a random dropout of 30 minutes to 2 hours, before resuming checks for x hours). What am I missing? I've looked into using different browsers, browser resources, internet connections, php timeouts etc. but this one is really head scratching. Thank you if you can help.
Ps. With a previous version I used to used the ajax- settimeout (5000) looping method, rather than the "recursion call to this same method" shown. This would literally run all day night without any dropping out - but I found that it would race itself from time to time, not waiting for the previous loop to complete. And therefore I might find 2 or 3 log entries for the same loop. How might I stabalize this loop to perform as I would like ? Thanks.
If you have similar: How can I make setInterval also work when a tab is inactive in Chrome?
If your script/jsfiddle is logging to the console, simply route it to the page title eg. document.title= 'your setInterval output'; ..so you'll better be able to detect what your interval loop is doing as you switch tab etc.
I've an ajax request to the server and I only need to know when it finishes to redirect the user to a second page. It is working most of the times but if the server takes too long to answer (e.g. 10 min) then it can happen that no callback function is called and the request keeps waiting.
My code is as follows:
$.ajax({
type: 'post',
url: 'request.php',
success: function(data) {
alert("Success: "+data);
window.location.replace("success.php");
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Ajax error: "+xhr.status+" - "+thrownError);
window.location.replace("error.php");
}
});
As you can see, I've tried to check if there is any error but as far as I have arrived, the ajax request behaves as if it had not finished (no alert or redirection is fired). However, the PHP code in the server runs without errors until the end.
I have no idea where to search for the error because I was thinking about a timeout problem both in the browser or in the server but it seems not to be the cause. And as the same code is working in short waiting times I cannot imagine other possible reasons.
Thank you!
I would bet on a timeout on your web server which invalidates the connection, this might mean that no answer is sent back.
In that case, the ajax timeout option might be good for you.
Having said that, if I were you, I would do this differently: since you're already using ajax, why not ping the server every x seconds and check if the process has finished and it's time to redirect, instead of keeping the connection open? This way you don't have timeout issues, and you don't hold the connection captive over a session which doesn't send any data and only waits for a server side process to finish. More scalable and robust, and more appropriate for http connections.
I am new to Comet programming. I searched through and write the code like this
<script type="text/javascript" charset="utf-8">
function waitForMsg(){
$.ajax({
type: "GET",
url: "getMessage.php",
async: true,
cache: false,
timeout:50000,
success: function(data){
$('#messages).append(data);
setTimeout(
'waitForMsg()',
1000
);
},
error: function(XMLHttpRequest, textStatus, errorThrown){
addmsg("error", textStatus + " (" + errorThrown + ")");
setTimeout(
'waitForMsg()',
"15000");
},
});
};
$(document).ready(function(){
waitForMsg();
});
</script>
I am getting update from getMessage.php when ever i am passing a message to getMessage.php
But my doubt is i used
setTimeout('waitForMsg()',1000);
What this means. If we are calling waitForMsg() for every 1 sec then what is the difference between Ajax and Comet programming.
Regarding your example, the difference between Ajax and Comet depends on how getMessage.php responds to the request from the client.
Using Ajax, getMessage.php would return immediately even if there are no new messages to return. The client would then wait the specified interval and then send another request, again either receiving a new message or nothing at all. End result is that the quickest the client will ever update with a new message is the specified interval.
Using Comet, on the other hand, getMessage.php would not return until it has something to return. Meaning on initial request from the client it would check for new messages, if none are available it would sleep for a certain amount of time and check again. This process would continue until a new message is available or a timeout occurs, at which point the client would send another request to the server and the process starts over. End result in this case is that the client would appear to update instantaneously.
There are multiple kinds of COMET. You're using AJAX polling, but there are other techniques, like forever-frame, that do not involve polling.
Forever-frame uses a hidden infinitely long iframe that the server pushes script tags to as needed.
Also note that some uses of AJAX polling (e.g. as explained by the Wikipedia) do not include a setTimeout, since they immediately start a new AJAX request in the success handler.
Also (with the AJAX polling example), you can just use:
setTimeout(waitForMsg, 1000);
There is no need for a string.
I read a lot of questions, but they doesn't working in my case.
My situation is: my ajax query to database to insert infromation. But in my web-application user can click on buttons very quick so previous ajax query is not finished, and there is where bugs are appear.
All i need to do is a delay between queries, so future queries will do only after previous is done.
Here is a code:
$('#save').click(function(){
var user_input=$('#user').val();
var section=$('#section').val();
$('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
$.ajax({
url: 'submit_db.php',
type: 'POST',
data: 'section='+section+'&user_input='+user_input,
success: function(result){
$('#response').remove();
$('#loading_info').append('<p id="response">' + result + '</p>');
$('#loading').fadeOut(500, function(){
$(this).remove();
});
}
});
return false;
});
What i tested and not working: insert timeout:3000 into ajax - 1 query is ok, but after this, the whole application freezes; set timeout using ajaxSetup() - the same situation. Tested setInterval function and put ajax query to it - but after it there were no ajax, application opened an implementing php file and freezes.
This not working:
$('#save').click(function(){
var t=setTimeout(function(){
var user_input=$('#user').val();
var section=$('#section').val();
$('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
$.ajax({
url: 'submit_db.php',
type: 'POST',
data: 'section='+section+'&user_input='+user_input,
success: function(result){
$('#response').remove();
$('#loading_info').append('<p id="response">' + result + '</p>');
$('#loading').fadeOut(500, function(){
$(this).remove();
});
}
});
return false;
},3000);
});
And this is not working too:
$('#save').click(function(){
var user_input=$('#user').val();
var section=$('#section').val();
$('#loading_info').append('<p><img src="Images/loading.gif" alt="loading" id="loading"/></p>');
$.ajax({
url: 'submit_db.php',
type: 'POST',
timeout: 3000,
data: 'section='+section+'&user_input='+user_input,
success: function(result){
$('#response').remove();
$('#loading_info').append('<p id="response">' + result + '</p>');
$('#loading').fadeOut(500, function(){
$(this).remove();
});
}
});
return false;
});
And finally this is not work too:
$.ajaxSetup({
timeout:3000,
});
Thanks in advance
What I suggest is to create a boolean and disable any button.
Create a boolean called "buttonPressed", this is set to false. When a submit is made, you check in your code if "buttonPressed" is set to false. If this isn't set to false, skit the AJAX request, otherwise set the buttonPressed to true and do the AJAX request. When the request is done, set the buttonPressed back to false and a new buttonpress will be allowed.
The problem is propably in that: user clicks 3 times in second, and afeter 3 seconds of timeouts, three quersies and sended in one second.
Use setTimeout, but clear this timeout everytime user clicks, so every time user clicks, timer is reseted, and you don't have to worry about query "queue".
Other solution is to detect does timer working, and ignore or queue user click (queue by creating new timet with value of 3000 + rest time of the actual timer
Paul Peelen's answer is probably the best one for you, but another safe solution would be to queue your requests. It will allow your code to execute asynchronously but still sequentially and even (potentially) allows you to kill duplicate requests before they even leave the machine. The way I've done this is something like this:
Create an array to hold your requests.
When the user's action causes a request, throw it into the end of the queue.
Immediately call a queue processor. If a previous requests hasn't resulted in a response yet, do nothing -- just leave it in the queue. Otherwise, remove the first item from the queue and process it. At this point, you could also look through the other queued requests and remove duplicates, or push high-priority requests to the top of the queue.
When the response is received, send it to wherever it needs to go and tell the queue processor to process the next request.
It's actually pretty simple to build, and I'm sure there are better variations out there. If server stability is a possible issue, you should build in some sort of process to kill dead requests (zombies).
Use a sentinel variable so that only one request can happen at a time. If it makes sense for the user to be able to have more than one request going then implement a queue for the requests, where the call to process the next element in the queue happens after the previous request has been handled.
I'm writing code in PHP that analyzes user input.
I'm hoping to analyze it through a AJAX request using jquery.
I'd like to provide real-time feedback to the user while I'm preforming the calculations.
For example:
"Uploading your input", "Analyzing", "Preparing final result" and so forth.
How can I go abut doing this?
You will have to have a different back-end script do the processing than the one you are sending your request to. Your original ajax request can store the user input to be analyzed, and another process check for new data to work on regularly and start working when it finds some. That background process can then record its progress, e.g. using a file or a database.
The subsequent ajax requests will check that progress file or database entry and display the progress to the user.
Another (more complicated) solution would be to use Comet to push information on the status from the server to the browser. There is a comet plugin for JQuery in the works, as described in StackOverflow question 136012.
Assuming you have a service located at /service-status.php that checked the status of the job and returned a string you could do something like this in a interval.
var intervalId;
intervalId = setInterval( function() {
$.ajax({
type: "POST",
url: "/service-status.php",
data: "jobid=" + id,
success: function(msg){
if (msg === 'Finished') {
clearInterval( intervalId );
}
alert( "Status: " + msg );
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("He's dead Jim"):
clearInterval( intervalId );
}
})
}, 500);
This would poll your service every 500ms. It also assumes that you return 'Finished' when done. Adjust accordingly. I might put a counter in there too to clear the interval just in case so you don't DDOS your own server.