delay ajax request - javascript

What is the best way to set timeout that will force my page not to set more than one ajax request per minute
Thanks in advance!

I'd use a simple variable holding the timerId returned from setTimeout. Something like this:
var timerId;
var doRequest = function(){
if(timerId) return;
timerId = setTimeout(doRequest, 60*1000);
// ajax code here
};
This will throttle the request to once per minute. If you need to stop the setTimeout call, then simply add another boolean based off the user event you are watching for.

Related

Request URL until required data arrives

What is the best way to periodically request URL and cancel requests when required data is present in the response in plain Javascript?
Say, I am requesting posts URI that returns JSON and want to cancel requests when numberOfPosts attribute in response is equal than some N.
Thanks!
Combine setInterval() with your web service call and cancel the interval once you got the expected response via clearInterval().
MDN about setInterval():
Repeatedly calls a function or executes a code snippet, with a fixed time delay between each call. Returns an intervalID.
This is demonstration of setInterval approach from accepted answer that worked for me (getJSONResponse contains all request handling logic):
var POLL_INTERVAL = 50;
var URI = 'posts';
var timerId = setInterval(function() {
var response = getJSONResponse(URI);
if (response.numberOfPosts === N) {
// Process response
...
clearInterval(timerId);
}
}, POLL_INTERVAL);

Performance of Javascript Function that makes HTTP Request

I need a way of measuring the response time of a javascript function that creates an http request, that includes the response time of that http request. I do not have access to modify that funciton however.
Here's what I'm trying to do:
var startTime = performance.now(); //log start timestamp
foo.bar(); //The Function that generates an HTTP request
var endTime = performance.now(); //log end timestamp
var diffTime = endTime - startTime;
but that only captures the time it takes for the function to generate the request. Is there a way to capture the response time of the request that gets genearated in javascript?
You have to check the timestamp inside of the request callback.
EDIT:
If you want do measure this completely independently from the application (so just by adding another js file), I guess you can decorate XMLHttpRequest.
window.XMLHttpRequest = function () {...}
Your wrapper will need to have the same API, so that the app still works, and can also measure performance internally.
I would usually just hit F12 to bring up dev tools on any browser, go to the network tab, and look at the ajax call that is being made, that will tell you exactly how long the request and repose took with very fine grained details.
However, if you are looking to factor in the java-script that makes the ajax call then start your timer right before the call and stop it on the complete event of the ajax call (will require editing the function). that is the only way to catch it if it is asynchronous. And just guessing here based on your description that it is actually an async call, and that explains the behavior of the function just making the ajax call then returning - and not caring about the status or the response...
If you happen to be using jQuery in your inaccessible function, you can give this a shot:
$.when(foo.bar()).done(function()
{
console.log("Fired after ajax request is done!");
});
Take a look also at:
var obj = {
promise: function() {
// do something
}
};
$.when( obj ).done( fn );
or
var obj = {
promise: foo.bar()
};
$.when( obj ).done( callback );
or check out this great article http://www.erichynds.com/blog/using-deferreds-in-jquery
well, if you don't have an acces to the function or you can't edit the ajax call, you can create a listener. the strategy:
declare a flag befor the http request call
start the call
start a listener that loop every X mili-seconds and check for a finish status (outside the ajax function and after it is called)
you should ask yourself: which kind of variables are changed when this call is over? event a visual change on the ui can be used as a flag
and if you wonder how to create your listener.. it looks something like this:
function listener()
{
// do some checks here
if (done)
{
var endTime = performance.now(); //log end timestamp
var diffTime = endTime - startTime;
}
else
{
setTimeout(listener(), 100);
}
}
listener(); // activate the listener

Javascript requests

I have two checkboxes on selection of each one will raise a ajax request in order to get response from server. I need to call a method only once when there is atleast 2 seconds gap after the last request is made. Any idea? This means i do not want to call the methods when checkboxes are clicked continously for less than 2 seconds gap. How can i cancel the request made if the time gap between the requests in less than 2 seconds. Note that i want the method to be fired only once after the last request is not followed by other requests for 2 seconds.
var timeout;
clearTimeout(timeout);
timeout = setTimeout(function () { // call method }, 2000);
Note that i wan to excecute the method only once for the last request made.
You don't show any code, but assuming you already have a function doAjax() that does the ajax request, you can ensure it isn't called until two seconds after the last click in any two second period by using the setTimeout() function to do something like this:
var timerID;
document.getElementById("yourCheckboxIdHere").onclick = function() {
clearTimeout(timerID);
timerID = setTimeout(doAjax, 2000);
};
Note that doAjax does not have parentheses after it when passed as a parameter to the setTimeout() function.
If you need to pass parameters to your doAjax() function change the line with setTimeout() to:
timerID = setTimeout(function(){
doAjax(parameters, go, here);
}, 2000);

Sending jQuery ajax request on keyboard input

I'm sending an ajax request to the server on user's input to an <input> element, like this:
$('#my-input').bind("input", function(event){
// here's the ajax request
});
What bothers me is that it send unnecessarily many requests on every user's keyup, meaning that if the user types very fast, there are many unnecessary requests. So I get the idea that there should be a certain delay/timeout, which waits a certain time (50 miliseconds?) for the user to stop typing before sending the ajax request. That would be one problem solved.
But what about cases when the first ajax request haven't been completed before sending another request? (Typing 60 ms / char while ajax request taking 300 ms).
What is the best way to solve this problem (both idea- and code-based)?
You can use throttle function in underscore library. As its documentation says:
Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.
Even if you don't want to introduce a new library, you can still get idea about how this function works from its source code. In fact, a simple version of throttle function could be:
function throttle(func, delay) {
var timeout = null;
return function() {
var that = this, args = arguments;
clearTimeout(timer);
timeout = setTimeout(function() {
func.apply(that, args);
}, delay);
};
}
This jQuery throttle-debounce plugin is also helpful. Especially, the debounce function seems more suitable to your needs than throttle function according to its author:
Debouncing can be especially useful for rate limiting execution of handlers on events that will trigger AJAX requests
You could just use the setTimeout function. Every so often, see if the text hasn't changed, and if it hasn't, then process accordingly.
setTimeout(function() {
// Do something after 1 second
}, 1000);
You can set async: false in your ajax request so it will process second ajax call only after completion of first ajax request.
I'd go with #HuiZeng's answer, but just in case you want a slightly modified version.
Steps
Listen to keydown using a setTimeout that you can clear.
When it fires, check if you have a previous request in queue, if so abort it and fire a new one
Example:
var inputTimer = 0, req;
function onInput(e){
clearTimeout(inputTImer);
inputTimer = setTimeout( function(){
// You have access to e here
// Cancel any previous requests
req && req.abort();
req = $.ajax({/*...Do your magic here :)*/})
}, 100)
}

jQuery: delay interval of ajax function till previous run is completed

I've set up an AJAX page refresh with setInterval.
From time to time, the server is so slow that a new request is initiated before the previous one has completed.
How can I prevent that?
Use a timeout value that is shorter than your refresh interval. When the request times out, it will call the error handler so you'll need to differentiate between time out errors and other types of errors in the handler.
$.ajax({
type: "POST",
url: "some.php",
data: "name=John&location=Boston",
timeout: 5000, /* ms or 5s */
success: function(msg){
alert( "Data Saved: " + msg );
}
});
Docs at jquery.com. Example above from same source, but with added timeout value.
Use setTimeout instead, initiate another setTimeout only after receiving the result of the AJAX request. That way a refresh only happens after the specified period since the last refresh.
Instead of using a fixed, hard coded interval: Trigger the next refresh as the last step of handling the current one, e.g. in the "Success" (or "Complete") event callbacks.
You could add a variable that keeps track of the time the current request was sent, so that you can calculate a dynamic delay:
take current time T1
send asynchronous request
other stuff happens...
asynchronous request returns, callback executes
subtract T1 from current time
if result < your desired request interval, set delay value > 0
if result >= your desired request interval, set delay value = 0
call setTimeout with the delay value, initiating the next cycle
What I can tell you is, use a flag in your code.
Like (not what I actually recommend just a simple example)
var isWorking = false;
function doRequest(){
if(isWorking) return;
isWorking = true;
$.ajax({
...,
success: workWithResponse
});
}
function workWithResponse(){
/* doAnythingelse */
isWorking = false;
}
setInterval(doRequest,1000);
Something like that, its primitive but you will avoid race conditions.
Regards.

Categories

Resources