time period count of multiple settimeout calls - javascript

During several ajax requests, dependant functions are being called at certain period of time. My Question is, there any way to find the total time period(200+300+500) without using events in settimeout function.
//main ajax calls using following functions
setTimeout(function(){
avg(10,15,30);
alert('I am triggered at 2ms');//dependant function 1 (calculate avg)
},200);
setTimeout(function(){
total(50,100,30);
alert('I am triggered at 3ms');//df 2(calculate total)
},300);
setTimeout(function(){
vat_cal(180,12.5);
alert('I am triggered at 5ms');//df 3(calculate vat % for total)
},500);
Assuming that I don't know how many times the setTimeout is being used.
So that If time factor is known it makes easier to load the data with notification.
Multiple ajax requests are killing data loading time. If I know the total time (200+300+500 = 1000). I can notify the user to wait upto a second.

function avg(x1,x2,x3)
{
alert(x1+x2+x3)
}
function total(x1,x2,x3)
{
alert(x1+x2+x3)
}
function vat_cal(x1,x2,x3)
{
alert(x1+x2+x3)
}
$.when( avg(10,15,30),total(50,100,30), vat_cal(180,12.5) ).done(function( x,y,z ) {
alert("finish")
});

Your problem seems a bit vague. But if you want to repeat setTimeout() function for a several time, it'll be better to use setInterval() function.
I dont really get the result that you want, but it should work.

[Code is Here][1]
[1]: http://jsfiddle.net/asomani/2y0t60g5/2/
Use When and Then callback method and in the last ajax request complete call the time Calculate Method.
window.time1 = new Date().getTime();
function aCallback()
{
window.time2 = new Date().getTime();
total_time = (window.time2 - window.time1)
}
$.when($.ajax({
data: {test:"1"}
}), $.ajax({
data: {test:"1"}
}),$.ajax({
data: {test:"1"},
success: aCallback
}) ).done(function( x,y,z ) {
alert(total_time );
});

Related

Why my setInterval function doesn't stop

I need to write a setInterval function in javascript. Thi is the code:
var myTimer=setInterval(function(){
var time=0;
$.ajax({
url:'...'
type: "POST",
dataType:"",
success: function (response) {
if(response=="true" || time>=10000){
clearInterval(myTimer);
}
time=time+1000;
},
error: function () {
alert("FAIL");
}
});
},1000);
I don't know why It doesn't stop in clearInterval. Anyone can help me?
You've claimed that the code does "come in the 'if'", so I assume the clearInterval call is actually being made.
Given that, the most likely explanation is that the interval is being cleared (after all, select isn't broken), but before the first "true" response, you've already made more than one ajax call, and the other ones you're seeing are ones scheduled before the interval was cleared.
E.g., your code runs and:
Fires off ajax call #1, which takes more than a second to complete
Fires off ajax call #2
Ajax call #1 completes but isn't "true"
Fires off ajax call #3
Ajax call #2 completes and is "true", clearing the interval
Ajax call #3 completes
Mixing two separate asynchronous intervals (one via setInterval and one via ajax) is asking for trouble.
If the goal is to make the request once a second and stop when you get back "true", I would have the success handler schedule the next call, e.g.:
(function() {
var time = 0;
var started = 0;
start();
function start() {
started = Date.now();
$.ajax({
url: '...'
type: "POST",
dataType: "",
success: function(response) {
if (response != "true") {
// Schedule the next call to occur one second after we
// started the previous call; or almost immediately if
// the call took more than a second to complete
setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
}
time = time + 1000;
},
error: function() {
alert("FAIL");
}
});
}
})();
Let me illustrate the expected and the actual scenarios to make things clearer.
Scenario #1
The image below shows the case where all your ajax requests complete before one second. You will notice that ajax callback success (or error) functions will execute only before clearInterval (which is what you always expect).
Scenario #2
When some of your ajax requests take more than one second (which is probably what happens), then your ajax callbacks can fire before / after / before-and-after the clearInterval, which makes you feel that your setInterval doesn't stop.
Note that your time variable is useless because it's a function-scoped variable that you initialize to 0 every function call. And even if it's a global variable, it'll only clear the interval in the 11th success function callback, and nothing guarantees how long these 11 successful requests will take.
Solution
As T.J. Crowder suggested, it's better to schedule the next ajax call in the success callback of the previous one, which guarantees that your ajax requests fire sequentially (only one at a time).
Note: Because you edited your question after his answer, then you'll also need to edit the if condition like this:
success: function(response) {
if (response != "true" && time < 10000) {
setTimeout(start, Math.max(0, 1000 - (Date.now() - started)));
}
}

Periodically send ajax requests

There is a page and I want periodically to make "background" ajax requests. So the page is loaded then it should send ajax requests in a certain amount of time.
I might use cron for that. I have never use previously so I'm wondering if it would fit for that task. Is there any other more simple way?
P.S. The time delay will be about 5 minutes.
Since there is essentially an unknown delay between the time you send out an AJAX request and the time you receive a complete response for it, an oftentimes more elegant approach is to start the next AJAX call a fixed amount of time after the prior one finishes. This way, you can also ensure that your calls don't overlap.
var set_delay = 5000,
callout = function () {
$.ajax({
/* blah */
})
.done(function (response) {
// update the page
})
.always(function () {
setTimeout(callout, set_delay);
});
};
// initial call
callout();
Cron is run on the serverside and you are using HTML and AJAX, so you should solve this issue in Javascript :-)
By using something like setInterval you can keep executing a function, your case might be something like polling a url via AJAX:
function updatePage(){
// perform AJAX request
}
setInterval(updatePage, 5000);
Depending on your rails version you may be able to use periodically_call_remote, otherwise you'll need the jquery alternative that #Bitterzoet described.
More info in this question.
You can send ajax request in four second like this:
setInterval(get_news, 4000);
function get_news(){
$.ajax('/dashboards/get_news', {
type: 'POST',
success: function(result) {
if(result > 0){
$('#div_1').text("See "+result+" new messages");
$('#div_1').show();
}
else{
$('#div_1').css('display', 'none');
}
},
error: function() {
// alert("Error")
}
});
}
Are you using jquery? If so, you can implement this method:
// first, you need asing a callback timer
var timeout = 300; //milliseconds
// this method contain your ajax request
function ajaxRequest() { //function to ajax request
$.ajax({
url: "/url/to/request/"
}).done(function(data) {
alert("response is: " + data);
});
}
$(document).on("ready", function(){
//this method will be called every 300 milliseconds
setInterval(ajaxRequest, timeout);
});

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);

JavaScript: Continue with function after another function call finishes

Edits: http://jsfiddle.net/vol7ron/wQZdM/
The fiddle should be used to help illustrate what I'm trying to do and what's happening. The sub-selects should be populated with the second option value.
Original Question:
Not sure the best way to ask. I'm creating a testing script to autofill inputs on a form.
It includes a series of drop-down select boxes, which populate other select options in an onChange event. When trying to auto-populate the form, the sub-selects don't have any options.
console.clear();
// non-select inputs
$(':input:not([type="hidden"],[type="button"])').each(function(){
$(this).val($(this).attr('name')) // test value is simple input's name
});
// select inputs
var count=0, cutoff=7500;
$('select').each(function(){
var t = $(this);
var c = t.children('option');
while( c.length <= 1 && count < cutoff){
count++;
c = $(this).children('option'); // tried not using the cache'd variable
if (!(count % 10))
console.log(count, c.length, "No Options"); // debugging -- never exists early
setTimeout(function(){},0); // not really doing anything
}
t.val( c.eq(1).val() ); // set value to second option value
t.trigger('change'); // calls the onChange even if it doesnt exist
});
// verify it does have data
console.log($('#sub-select').children('option').length); // does have options
There's an AJAX call in the change event. I could modify the callback, but this is just a simple set script for testing, that is run from console. Any ideas?
Not really sure what your code is trying to do
But answering the question How to continue with function after another function call finishes :-
assuming you have a list of functions which are all asynchronous you can nest them to continue
to the next asynchronous function ...
asyncCall(callback1) {
callback1(callback2) {
callback2(...)
}
}
Checkout https://github.com/caolan/async for some elegant ways to do this
this example calls all functions in order even though they are asynchronous.
async.series([
function(callback){
setTimeout(function(){
call_order.push(1);
callback(null, 1);
}, 25);
},
function(callback){
setTimeout(function(){
call_order.push(2);
callback(null, 2);
}, 50);
},
function(callback){
setTimeout(function(){
call_order.push(3);
callback(null, 3,3);
}, 15);
}
1) Use Synchronous AJAX request http://api.jquery.com/jQuery.ajax/
var html = $.ajax({
url: "some.php",
async: false
}).responseText;
2) Instead of using the .each use .eq(index) and just call it in order.
function FakeEach(idx) {
if(idx >= 7500) return;
var $obj = $('select').eq(idx);
if($obj.length == 0) return;
...
$obj.trigger('change');
window.setTimeout(function() { FakeEach(idx++); }, 0);
}
Your problem is that you are starting an AJAX request in the function, and expect that the response arrives before the function ends. As long as you are using an asynchronous request, this will never happen. You have to exit your function before the code that handles the response can run. Javascript is single threaded, so as long as your function is running, no other code can run.
The solution to the problem is to put the code that uses the data in the success callback function that is called after the response has arrived. Eventhough you usually write that function inside the function that makes the AJAX call, it's a separate function that will run later.
If you really need the data in the same function as the AJAX call, you would need to make a synchronous request. This is a killer for the user experience, though, as the entire browser freezes while it is waiting for the response.

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