I've been struggling creating a reload functionality when a getJSON call fails. This is my current code:
function get_stuff(page) {
fPage = 'http://mywebsite.com/' + page + '.json';
$.getJSON(fPage, function (data) {
// Stuff
})
.fail(function () { // Call failed
get_stuff(page);
});
This code does reload the function, but a couple of times every millisecond. I thought of adding a delay, however I didn't manage to find a function (I tried delay(ms) and sleep(ms))
I hope anyone is able to help me out
setTimeout(function, ms)
Example
setTimeout(function(){
get_stuff(page)
}, 1000)
// the function will be executed after 1 second
Related
I have an Ajax call which I want run multiple times till it satisfies a particular if condition. The AJAX call gives you the job status-Running, Queued and Complete.
I am unable to get the Job status- Complete. After getting Running status it takes a couple of minutes to get the status Complete. So far I have tried the following JS. I also want to break the loop after the if condition has been met. I am also not sure if I should run the call for 100 times as it might take more than that. Thank you for your help.
My JS:
var pollForJob= gallery.getJob(jobId, function(job){
var jobStat=job.status;
console.log(jobStat);
if(jobStat=="Complete"){
alert("Complete");
} else {
// Attempt it again in one second
setTimeout(pollForJob, 1000);
console.log("still working");
console.log(jobStat);
}
}, function(response){
var error = response.responseJSON && response.responseJSON.message ||
response.statusText;
alert(error);
// Attempt it again in one second
setTimeout(pollForJob, 1000);
});
Like Jeremy Thille said, this is called long polling. A simple way of doing it is to create a function which makes the call out to the server. Then, if it fails, use setTimeout to queue up another request later.
function pollForJob() {
gallery.getJob(jobId, function(job) {
var jobStat = job.status;
if (jobStat == "Complete") {
alert("Complete");
} else {
// Attempt it again in one second
setTimeout(pollForJob, 1000);
}
}, function(response) {
var error = response.responseJSON && response.responseJSON.message || response.statusText;
console.error(error);
// Attempt it again in one second
setTimeout(pollForJob, 1000);
});
}
pollForJob();
I have this function. Basically it searches data from database and does something with it. In this demo it just increases counter.
exports.fullThreads = function(){
return new Promise((resolve, reject) => {
MongoClient.connect(mongoUrl, (err, db) => {
var fullThreads = db.collection('tmp_fullThreads'),
threadPages = db.collection('tmp_threadPages').find();
var counter = 0;
threadPages.on('data', (doc) => {
setTimeout(function(){
counter++;
}, 200)
});
threadPages.on('end', () => {
console.log('end');
console.log(counter);
});
});//connect
});//promise
}//fullthreads
In this example I expected that it would call for data, wait 200ms, and then increase counter. Once it reaches the end, it would end. However it is different. on('end') is called before on('data') actually finished. I guess that is because it didn't return value immediately. So this setTimeout function is not a way to go. However I have a real problem here. This is simply way too fast and in real life code, this wouldn't increase counter, it would call foreign API which doesn't accept so many calls in so little time, so I wanted to make a delay between each call, how is this done properly?
Then you would need some kind of queu
eg:
queuTasks = [];
queuTasks.push("Task1");
queuTasks.push("Task2");
function doTasks(){
// Do your task
if(queuTasks.length > 0){
console.log(queuTasks[0]);
queuTasks.splice(0,1); // Remove it from the queu
}
setTimeout(function(){ doTasks();}, 1000);
}
This is just some quick code i made, may not work out of the box. But think you get the idea.
I know this is not entirely what you were asking about
This is my workaround:
var threadPages = db.collection('tmp_threadPages').find();
var delay = 0;
function test(doc, delay){
setTimeout(function(){
console.log(delay);
}, delay)
}
threadPages.on('data', (doc) => {
test(doc, delay);
delay += 100;
});
It works well if you do not need to bind proper events to on('end method. Basically it increases delay per request, otherwise it would fire all of them at once. This makes code go slower and it wouldn't overkill API with too many requests per second.
I am pretty new in JavaScript and I have to perform an operation after some time that another previous operation is performed.
So I have this function:
function validaProgetti() {
$.ajax({
type: "POST",
//data: {'checkedRowList' : checkedRowList},
data: JSON.stringify(checkedRowList),
url: "validaProgetti",
contentType:"application/json"
}).done(function(response) {
$('.modal').modal('hide');
sostituisciFrammentoJsp('outputRicerca', response);
//alert("SUCCESS");
}).error(function(xhr) {
alert("ERROR");
manageError(xhr);
});
}
As you can see into the done() body I have these 2 call:
$('.modal').modal('hide');
sostituisciFrammentoJsp('outputRicerca', response);
I need that the sostituisciFrammentoJsp() execution is performed after 3 seconds of delay to ensure that the previoius function is complete.
How can I correctly set a delay for this function?
...after 3 seconds of delay to ensure that the previoius function is complete.
Let's do better than that, and actually wait for the previous function to complete:
$('.modal').modal('hide').one("hidden.bs.modal", function() {
sostituisciFrammentoJsp('outputRicerca', response);
});
(Note I used one, not on, so the handler gets autoremoved after the event occurs.)
Note that I've assumed there you're using a Bootstrap modal, but other "modal" libraries will offer a similar event or callback.
But answering the question you actually asked, you can set up a callback after three seconds with setTimeout:
$('.modal').modal('hide');
setTimeout(function() {
sostituisciFrammentoJsp('outputRicerca', response);
}, 3000);
The number at the end is in milliseconds (thousanths of a second).
Just use javascript setTimeout
setTimeout(function(){
// your code here
}, timeInMillis);
Using this command will schedule an operation for the time you pass.
Option : 1
clearTimeout(window.timer);
window.timer=setTimeout(function(){ // setting the delay for each keypress
ajaxSearchRequest($type); //runs the ajax request
}, 3000);
Option : 2
// set your delay here, 2 seconds as an example...
var my_delay = 2000;
// call your ajax function when the document is ready...
$(function() {
callAjax();
});
// function that processes your ajax calls...
function callAjax() {
$.ajax({
// ajax parameters here...
// ...
success: function() {
setTimeout(callAjax, my_delay);
}
});
}
I have the following scenario:
I have a javascript ajax function loadCars() that needs to be called after the page loads in 10 seconds, and then every 60 seconds.
The below is what I have tried so far:
setTimeout(function(){setInterval(function(){loadCars()}, 60000)}, 10000);
What is happening is that the function is being called after 10 seconds but never again, what am I missing?
You need to call loadCars on setTimeout and on setInterval.
setTimeout(function() {
console.log('first 10 secs');
// loadCars();
setInterval(function() {
console.log('60 secs has passed');
// loadCars();
}, 60000);
}, 10000);
console.log('page loaded');
I don't agree with the answers given because they use setInterval or don't wait for the ajax call to be finished. IMO your should set a new timeout only when the function loadcars (and the ajax call) has finished.
Example:
function loadCars () {
// ajax call happens here
$.ajax()
.then(function(){
// call the function here
setTimeout(function(){
loadCars();
// wait a minute after you recieved the data
}, 60000)
})
}
// wait 10 seconds
setTimeout(function(){
loadCars();
}, 10000)
The advantage if this is that it will only start setting a new timeout when the HTTP request is finished and prevent the function from getting out of sync. If you use setinterval in combination with an ajax call then the next ajax call will happen in 60 seconds even if the current one is delayed for 10 seconds (and you don't want that).
You can call setTimeout(loadCars, 60000) in your loadCars() method that way you call it once initially with setTimeout 10 seconds then from that point it sets a timeout for 1 minute out every time it executes...
function loadCars()
{
//code
setTimeout(loadCars, 60000);
}
setTimeout(loadCars, 10000);
If you want the next timeout to be scheduled only after ajax call is completed then either make a synchronus ajax call or put the setTimeout() in your success callback of your ajax call...The latter being the better option.
To get more control over timings and function calls you could specify them all this way:
function loadCars() {
$('#log').append('Cars loaded<br />');
};
function loadManufacturers() {
$('#log').append('Manufacturers loaded<br />');
};
function loadCustomers() {
$('#log').append('Customers loaded<br />');
};
function loadContent(delays, functions) {
if (functions.length) {
setTimeout(function () {
functions.pop()();
loadContent(delays, functions);
}, delays.pop());
};
};
loadContent([3000, 2000, 1000], [loadCars, loadManufacturers, loadCustomers]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p id="log"></p>
Playground
I'm using a function to fetch data from webapi. Basicly using $.ajax.
I'm now testing it with waits() like this:
describe('xxxxxxxxxxxxxxxxxxxxx', function () {
var r;
it('fetchFilter', function () {
runs(function () {
model.fetch(opts)
.done(function(data) {
r = data;
});
});
waits(2000);
runs(function () {
expect(r[0].gender).toBeDefined();
});
});
});
The problem is:
It's not guaranteed that waits(2000) will do the job well. Due to various reasons(network connections, algorithm efficiency of the api it self, etc.), I may have to waits(5000) or more, or for some models waits(500) is enough. And the most annoying thing is that it's all out of control.
A lot of waits() makes the test-specs-runs waste a lot of time waiting. The time of running the whole suite is too long to accept.
Is there some best practice of doing there kind of things?
PS: I know that unit test should not be applied to some function that relies on webapi or database. But I'm working with a single-page-js-heavy-webapp. The data fetching process is as important as how I will consume them with js models.
waitsFor() will wait for a specified latch callback to return true (it will try many time every few ms). It will also raise an exception if the specified timeout (5000ms in this case) is exceeded.
describe('xxxxxxxxxxxxxxxxxxxxx', function () {
var r, fetchDone;
it('fetchFilter', function () {
runs(function () {
model.fetch(opts).done(function(data) {
r = data;
fetchDone = true;
});
});
waitsFor(function() {
return fetchDone;
}, 5000);
runs(function () {
expect(r[0].gender).toBeDefined();
});
});
});
Check the Jasmine docs for more info on waitsFor() and runs()
The following solution allows you to wait no more than really necessary but still you have to define max timeout you suppose to be enough.
The waitsFor takes the function and waits until it returns true or the timeout passed as the last argument expired. Otherwise it fails.
Supposing the thing you need to wait for is that r[0] is defined at all, it could be:
waitsFor(
function() { return r[0]; },
'the data should be already set',
5000);
As per jasmine 2.5, you can pass an extra paramater for it("scenario", callback, timeout)
describe('xxxxxxxxxxxxxxxxxxxxx', function (done) {
var r, fetchDone;
it('fetchFilter', function () {
runs(function () {
model.fetch(opts).done(function(data) {
r = data;
fetchDone = true;
});
});
setTimeout(function() {
done();
}, 9000);
runs(function () {
expect(r[0].gender).toBeDefined();
});
});
},10000);