I have a function that uses "post" to get data from the server and process it. Amount of data varies and the function can take a long time to complete (30 seconds). I would like for the function to be called repeatedly but only 10 seconds after it has completed the previous iteration. *Result of the function is stored in a global and is used in the next iteration of the same function.
I've tried setInterval and setTimeout but neither one of those seem to give me the result I'm looking for.
Any thoughts?
function foo(){
$.post( "test.php", { name: "John", time: "2pm" })
.done(function( data ) {
// do your stuff with returned data
// and call itself again...
setTimeout(foo, 10000);
});
}
Wouldn't this approach work?
function a(){
//do stuff
setTimeout(a, 10000); //has to be at the end of the execution. If you're doing things asynchronously that's a different story.
}
function setTimeout() can be used for this. But the method must be invoked for the first time then the function itself invoke the method again.
function method(){
console.log('method invoked');
setTimeout(method, 10000);
}
method();
var $id = 1;
var Interval ;
$(function(){
callAjax();//Starts Interval
});
functoin callAjax()
{
Interval = setInterval(function () {
try {
if($id > 0)
{
$.ajax({
url: _MyUrl + $id,
success: function (calbkData) {
$id = 0;
if (parseInt(calbkData.id) > 0) {
$id = calbkData.id;
OpenMsg(calbkData.id);
}
},
global: false, // this makes sure ajaxStart is not triggered
dataType: 'json'
//,complete: longpoll
});
}
} catch (e) {
// alert(e);
}
}, 10000);
}
This is working very fine, for me.
function Test()
{
//Your code here
setTimeout(Test(),10000);
//Its used to set time interval after your iteration is run
}
Related
I am reading a project that I have to work and do additional work on, but I don't understand some interval trickery that has been done and not explained by the previous person. That's the code:
var intervalId;
var intervalIdtwo;
$(document).on('click', 'li.mention-individuals', function() {
clearInterval(loadTimer);
var otheridFromSearch = $(this).data('profileid');
var searchImage = $(this).find('img.search-image').attr('src');
var searchName = $(this).find('.mention-name').text();
$('.users-right-pro-pic img').attr('src', searchImage);
$('.users-right-pro-name').text(searchName);
$('.user-info').attr("data-otherid", otheridFromSearch);
xyz(useridd, otheridFromSearch, abc);
$.post('http://localhost/facebook/core/ajax/message.php', {
showmsg: otheridFromSearch,
yourid: useridForAjax
}, function(data) {
$('.msg-box').html(data);
$('.user-show').empty();
$('.top-msg-user-photo img').attr('src', searchImage);
$('.top-msg-user-name').text(searchName);
scrollItself();
})
if (!intervalId) {
intervalId = setInterval(function() {
loadMessageFromSearch(useridForAjax, otheridFromSearch);
}, 1000);
clearInterval(intervalIdtwo);
intervalIdtwo = null;
} else if (!intervalIdtwo) {
clearInterval(intervalId);
intervalId = null;
intervalIdtwo = setInterval(function() {
loadMessageFromSearch(useridForAjax, otheridFromSearch);
}, 1000);
} else {
alert('Nothing found');
}
})
function loadMessageFromSearch(useridForAjax, otheridFromSearch) {
var pastDataCount = $('.past-data-count').data('datacount'); //if no new data, the old messages will be shown
$.ajax({
type: "POST",
url: "http://localhost/facebook/core/ajax/message.php",
data: {
showmsg: otheridFromSearch,
yourid: useridForAjax
},
success: function(data) {
$('.msg-box').html(data);
}
})
$.post('http://localhost/facebook/core/ajax/message.php', {
dataCount: otheridFromSearch,
profileid: useridForAjax
}, function(data) {
if (pastDataCount == data) {
console.log('data is same');
} else {
scrollItself();
console.log('data is not same');
}
})
}
I generally get the code, but the Ifs section with the IntervalId and IntervalIdTwo - I have no clue what it does. Any tips or explanations would be greatly appreciated!
On the surface, the setInterval function is simple: it takes a function and a number n and calls the function (at most) every n milliseconds. It also returns a "handle" that allows you to cancel the repeated invocations by calling clearInterval with the handle.
For instance, here is a function that logs a string to the console:
function sayHello() {
console.log('hello!');
}
We can call it every second (1000 milliseconds) like so:
setInterval(sayHello, 1000);
(You can even try it out in your browser's dev. tools right now! It should print 'hello!' every second)
What if we want to stop printing 'hello!'? If we "hold onto" the return value, we can cancel the repeated invocations:
const handle = setInterval(sayHello, 1000);
(If you're curious, try printing handle!)
To cancel the process, call the clearInterval function with the handle:
clearInterval(handle);
A couple of notes:
In a lot of cases, it is a pain to define a separate function like sayHello, so we would instead use an "anonymous function", like:
setInterval(function() {
console.log('hello!');
}, 1000);
// or
setInterval(() => console.log('hello!'), 1000);
This underscores the fact that setInterval is a higher-order function: it takes another function as one of its arguments. This can take some getting used to, but with practice it becomes second nature.
Depending on how "busy" your browser is, the invocations may not take place at exactly the interval you specify. The delay may be longer than the number you provide, but never shorter (see 3. below for why).
if you really want to grok setInterval you will need an understanding of JavaScript's concurrency model.
I have the following JS code:
var delay = 5000;
function init() {
setInterval(getFileCount, delay);
}
function getFileCount() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
// Do stuff with response
});
}
On page load I'm calling the init() function. The idea is to start the interval and call the getFileCount() function every 5 seconds.
So, the interval waits 5s after the page loads and runs, but it always makes the Ajax call twice.
What am I missing?
UPDATE:
I know the init() function is triggered twice on page load (thanks to the comment by Yury Tarabanko). I don't quite understand, why. The almost-full code:
$(function() {
'use strict';
function handleCourseNotification() {
var delay = 5000;
function init() {
setInterval(getFileCount, delay);
}
function getFileCount() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
updateCourseList(response.items);
});
}
function updateCourseList(items) {
// update course list...
}
return {
init: init
};
}
if ($('#js-auth-course-list').length) {
var notificationHandler = handleCourseNotification();
notificationHandler.init();
}
});
It's a small module, which I initialize after page load, if a specific element is available in the DOM - $('#js-auth-course-list'). Why is init called 2 times actually? I directly call it once.
In general, it is not a good idea to call asynchronous calls inside a setInterval() because you do not know the exact response time. So, you could end up calling the second async function before the response from the first call has returned.
You can try with setTimeout() like this:
var delay = 5000;
var async = function() {
$.get('/notification/course-file-count', function(response) {
if (response.items.length === 0) {
return false;
}
// Do stuff with response
// Call the async function again
setTimeout(function() {
async();
}, delay);
});
}
async();
So Javascript is not multithreaded. But I have the following problem.
I use AJAX calls from a function called from setTimeout. I need to know be able to distinguish when there are active AJAX calls before rescheduling the function.
For that I am using 2 global variables. So the code structure is as follows:
setTimeout(some_function, 10000);
window.ajax_running = 0;
window.calls_so_far = 0;
function some_function () {
if(window.ajax_running) {
setTimeout(some_function, 10000);
return;
}
window.ajax_running = 1;
$.ajax({
//various
success: function (data) {
window.calls_so_far = window.calls_so_far + 1;
console.log('Running calls: ' + window.calls_so_far);
if(window.calls_so_far >= SOME_VALUE) {
//we are ok ajax has finished
window.ajax_running = 0;
}
}
Simple code. The problem is that it does not work. I see in the console:
Running calls: 1
So the global variable is not being incremented. It is as is each AJAX call sees the original value 0 and increments it (like as if there were threads).
What am I messing up here? How can I fix this?
When success runs, the ajax call had already finished, so you are not running this call when u add calls_so_far.
I'm not sure why u need the call to be "counted", but if is just the other problem (to call the same function after the first had finished, i would suggest this approach:
var counter;
counter = 0;
function recallSomeFunction() {
setTimeout(some_function, 10000);
}
function some_function () {
$.ajax({
//various
success: function (data) {
if (++counter < SOME_VAL) recallSomeFunction();
//...
},
error: function ( jqXHR, textStatus, errorThrown )) {
recallSomeFunction()
//...
});
}
Can someone please explain to me what is wrong with my code below? I am declaring a public variable and setting it to a setTimeout, and if not null, clearing the timeout before it gets set again. When I try to clear the timeout I get undefined so the timeout continues to run.
var usernameCheckTimeout = null;
$(document).ready(function(){
$("#username").on("keyup", function(e){
if($(this).val().length >= 6)
{
if(usernameCheckTimeout != null)
{
clearTimeout(usernameCheckTimeout);
}
usernameCheckTimeout = setTimeout(isUsernameAvailable($(this).val()), 1000);
}
});
});
function isUsernameAvailable(username)
{
$.ajax({
url : "/account/username-check",
method : "POST",
dataType : 'json',
data : {
'username' : username
}
}).done(function(data) {
console.log(data);
});
};
You do not need to do the null check also you need to create a closure around this, otherwise this will refer to not what you think this actually is.
var usernameCheckTimeout;
$("#username").on("keyup", function (e) {
if ($(this).val().length >= 6) {
clearTimeout(usernameCheckTimeout);
var that = this;
usernameCheckTimeout = setTimeout(function () {
isUsernameAvailable($(that).val();
}, 1000);
}
});
Some jsfiddle love like usual.
The timeout is being cleared. The problem is that you are calling your function immediately instead of passing the function to setTimeout.
setTimeout(isUsernameAvailable($(this).val()), 1000);
isUsernameAvailable($(this).val()) will be called and the result of this call will be passed to setTimeout.
You should instead pass a function which calls this function:
EDIT: As #Mark said, you also need to deal with this not being what you expect:
var value = $(this).val();
setTimeout(function(){
isUsernameAvailable(value)
}, 1000);
You have a couple of issues. The first issue, which is huge, is that you are executing isUsernameAvailable($(this).val()) immediately and passing the return value to setTimeout - you need to move this into an anonymous function so it does not execute until the anonymous function is called by the timeout:
usernameCheckTimeout = setTimeout(function () {
isUsernameAvailable($(this).val());
}, 1000);
the javascript timeout functions rely on numeric IDs to function. You should avoid testing for null or undefined or anything else, and instead test for a number:
// leave it as undefined
var usernameCheckTimeout;
...
if (typeof usernameCheckTimeout === 'number') {
clearTimeout(usernameCheckTimeout);
}
Ok. here's the scenario:
function DataFeed(){
function PopulateData()
{
$('div#example').load('http://www.example.com', fxnCallBack);
};
function fxnCallBack()
{
PopulateData();
}
this.activator = function() {
PopulateData();
}
};
var example_obj = new DataFeed;
example_obj.activator();
In the above code, the ajax .load gets executed once, then callback executes. But the callback doesn't start the ajax function again?
Thanks in advance.
edit- why doesn't it display new line properly -.-
InternalError: too much recursion
JavaScript engines normally have a max limit in the number of recursions or the time recursive execution may take. Use setInterval instead:
function DataFeed() {
var interval;
function PopulateData() {
$('div#example').load('http://www.example.com', function(data) {
if(data == "clear_interval")
interval = clearInterval(interval); // clear the interval
});
}
this.activator = function() {
interval = setInterval(PopulateData, 1000); // run every second
};
}
var example_obj = new DataFeed();
example_obj.activator();