Why the timeout don't work?
If i work without the function sleep, they return to me an undefined data..
With this function they work but without sleeping time, they go directly to the last image.. :-/
function sleep(value, data, i) {
document.getElementById(value).src = data[i];
}
function imgAnimation(value){
var img = document.getElementById(value).src;
$.ajax({
type: "POST",
url: "static/cercaThumbs.php",
data: 'id=' + value,
datatype: 'json',
success: function (data) {
var elements = Object.keys(data).length;
for (var i = 0; i < elements; i++) {
if(i == elements){i = 0;}
setTimeout(sleep(value, data, i), 300);
}
}
});
}
You need to pass a function to setTimeout. You're calling the function sleep and passing its result.
setTimeout(function() {
sleep(value, data, i);
}, 300);
But it still won't work, because you're setting a bunch of timeouts at the same time, so they'll all trigger 300ms later at the same time. To animate you might try something like:
var data = [
'https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.2/assets/png/0030.png',
'https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.2/assets/png/0031.png',
'https://cdnjs.cloudflare.com/ajax/libs/emojione/2.2.2/assets/png/0032.png',
]
var frame = 0;
var elements = data.length;
var animation = setInterval(function() {
frame = (frame + 1) % elements;
document.getElementById('test').src = data[frame];
}, 300);
<img id=test>
This sets up a single repeating callback which can advance to the next frame each time. In the example above it will loop forever, or you can call clearInterval(animation) once you're finished.
Ok, with the help of Nick, this is the correct code:
function imgAnimation(value){
$.ajax({
type: "POST",
url: "static/cercaThumbs.php",
data: 'id=' + value,
datatype: 'json',
success: function (data) {
var elements = Object.keys(data).length;
var frame = 0;
var animation = setInterval(function() {
frame = (frame + 1) % elements;
document.getElementById(value).src = data[frame];
}, 500);
document.getElementById(value).addEventListener("mouseout", function(){
clearInterval(animation);
document.getElementById(value).src = data['0'];
});
}
});
}
Related
I have an AJAX call that gets called "i" amount of times. I want to execute the rest of the code only after the last AJAX processData callback function was finished (It fills values of the .csv into an array called "lines" and I need the finished array after all iterations have finished). So far it only works by using "setTimeout()" which is not a nice solution
for (var i = 0; i < options.length; i++) {
(function(index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type)
}
});
})(i);
}
setTimeout(function() {
getAveragePercentages(lines);
}, 500)
You can use the JavaScript promise functionality.
Make AJAX request in the promise.
Create an array which will contains all these promise.
Promise.all will be executed after all promise get resolved.
var promiseArr = [];
for (var i = 0; i < options.length; i++) {
var promise = new Promise(function(resolve, reject) {
(function(index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type); resolve('outputIfany')
}
});
})(i);
});
promiseArr.push(promise);
}
Promise.all(promiseArr).then(function(values) {
getAveragePercentages(lines);
});
for (var i = 0; i < options.length; i++) {
(function (index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function (data) {
processData(data, options[index], type)
}
});
counter = counter + 1;
})(i);
if (i == options.length) {
getAveragePercentages(lines);
}
}
You can do something like this.
after last Loop Success call function
var totalRec = options.length;
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {processData(data, options[index], type)
if(i == (totalRec-1)){
getAveragePercentages(lines);
}
}
});
})(i);
}
or
var totalRec = options.length;
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {processData(data, options[index], type)
}
});
})(i);
if(i == (totalRec-1)){
getAveragePercentages(lines); // gets called only when condition is true
}
}
It is not a good practice to use a setTimeOut for wait the ajax call, in my experience I've been using recursive functions for doing this, in your case you can do the following:
var counter = 0;
function main()
{
counter = 0;
doAjaxCall(counter);
}
function doAjaxCall(counter)
{
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type);
if(counter < options.length)
{
counter++;
doAjaxCall(counter); //We call the same function but with the next index
}
else
{
//The loop finished, countinue code after your for loop
}
}
});
})(i);
}
set up a counter and check it's value before calling your function
$("#counter").html("0");
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type)
var counter = $("#counter").html();
if( counter == options.length ){
getAveragePercentages(lines);
}
$("#counter").html(counter+1);
}
});
})(i);
}
I added a function as a parameter. The AJAX calls the function when the load is completed.
function loadDoc(call_back_func) {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
json_data = JSON.parse(this.responseText);
call_back_func();
}
xhttp.open("GET", "kanban_personal_template.json");
xhttp.send();
}
function load_call_back()
{
console.log(json_data);
}
loadDoc(load_call_back);
For the following code, the emailCnt is 50 for first iteration, I need 25 in next iteration. What is the possible way to access the variable value outside the ajax success and break the for loop execution?
var limit = 50;
var emailCnt = limit;
for (var i = 0; i < 20; i++) {
console.log(emailCnt);///this value is 50 instead I need 25
if (emailCnt < limit && i != 0) {
break;
}
setTimeout(function () {
submit_post(slNo, limit, function (output) {
slNo = output;
emailCnt = 25;
$('#load_data').html('Hello');
});
}, 1000);
}
function submit_post(slNo, limit, handleData) {
$.ajax({
type: 'POST',
async: false,
url: url,
data: { slNo: slNo, limit: limit },
success: function (data) { handleData(data); }
});
}
This successfully worked for me
var limit = 50;
var emailCnt = limit;
function submit_post(slNo, limit)
{
var result="";
$.ajax({
type: 'POST',
async: false,
url: url,
data: {slNo:slNo, limit:limit},
success: function(data) { result = data; }
});
return result;
}
for(var i=0;i<20;i++)
{
if(emailCnt < limit && i != 0)
{
break;
}
setTimeout(function () {
var output = submit_post(slNo, limit);
slNo = output;
emailCnt = 25;
$('#load_data').html('Hello');
}, 1000);
}
I want to set global variable from function and loop ajax to get distance.
However the nearestIndex variable is always undefined.
First solution I got was to use async: false - this is work in my pc browser, but this project is webservice to android, and this solution not work to webview.
And of course async: false not recommended. I need this example in my case, I've been looking for this problem in stack overflow, but i always failed to understand about callback.
var allDestination = ["A", "B", "C"];
var nearestIndex;
function getNearest(){
var from = myPosition.getLatLng().lat + "," + myPosition.getLatLng().lng;
var tempDistance;
for(var i=0; i<allDestination.length; i++){
var destination = allDestination[i].getLatLng().lat + "," + allDestination[i].getLatLng().lng;
$.ajax({
type: "GET",
url: "http://localhost:8989/route?point=" + from + "&point=" + destination + "&points_encoded=false&instructions=false",
dataType: 'json',
contentType: "application/json",
success: function (data) {
var distance = data.distance;
if(i == 0){
tempDistance = distance;
nearestIndex = i;
} else {
if(distance < tempDistance){
tempDistance = distance;
nearestIndex = i;
}
}
}
});
}
}
function onMapClick(e) {
myPosition.setLatLng(e.latlng);
myPosition.addTo(map);
getNearest();
allDestination[nearestIndex].addTo(map);
}
As you are dealing with Async call; your relevant code has to get called from success handler of ajax call as follows:
var allDestination = ["A", "B", "C"];
var nearestIndex;
var tempDistance;
var successReceived = 0; //counter to keep watch on ajax success callback
//modify the function signature to receive index as well as callback function
function getNearest(index, callbackFunction) {
var from = myPosition.getLatLng().lat + "," + myPosition.getLatLng().lng;
var destination = allDestination[index].getLatLng().lat + "," + allDestination[index].getLatLng().lng;
$.ajax({
type: "GET",
url: "http://localhost:8989/route?point=" + from + "&point=" + destination + "&points_encoded=false&instructions=false",
dataType: 'json',
contentType: "application/json",
success: function(data) {
successReceived++; //increment the success counter
var distance = data.distance;
if (index == 0) {
tempDistance = distance;
nearestIndex = index;
} else {
if (distance < tempDistance) {
tempDistance = distance;
nearestIndex = index;
}
}
//check if we got all the ajax response back. If yes then call the callback function
if(successReceived == allDestination.length && typeof callbackFunction == 'function')
{
callbackFunction();
}
}
});
}
function onMapClick(e) {
myPosition.setLatLng(e.latlng);
myPosition.addTo(map);
for (var i = 0; i < allDestination.length; i++) {
//pass the current index and callback function
getNearest(i,function(){
allDestination[nearestIndex].addTo(map);
});
}
}
I ever have got the same problem like you,
it because asincrounous function cant return anything.
so I think you shoud inject allDestination[nearstIndex].addTo(map); into ajax success
if(i == 0){
tempDistance = distance;
allDestination[i].addTo(map);
} else {
if(distance < tempDistance){
tempDistance = distance;
allDestination[i].addTo(map);
}
}
or you create function to handle ajax success,,, CMIIW
I have a program which calls a function in javascript with 1 o more requests to 1 servlet, I want to execute request after request and get the response after each exucution, to make this I have 1 function, but it only shows the result after all requests have been executed.
function cmd(args) {
width = 0;
var res = args.split('\n');
var largo = res.length;
var progressLength = 100 / largo;
for (var i = 0; i < largo; i++)
{
if (res[i] == 'desconectar')
{
desconectar();
break;
}
else
{
executeCMD(res[i]);
}
}
}
function executeCMD(args)
{
$.ajax({
type: "POST",
url: 'Controlador',
data: {cmd: args, operacion: 1},
success: function (response) {
document.getElementById('respuesta').value = document.getElementById('respuesta').value + response;
},
dataType: 'text',
async: false
});
}
If I add window.alert(response); inside success field it shows the progress step by step and works fine, but it show alerts which I don't want.
This is I want http://imgur.com/a/9nclR but I'm getting only last picture.
The solution if anyone is intersting was using a recursive function as next:
function cmd(args) {
width = 0;
move(0);
var res = args.split('\n');
var largo = res.length;
var valInit = 0;
if (largo > valInit)
{
executeCMD(res, valInit);
}
}
function executeCMD(args, i)
{
$(document).ready(function () {
$.ajax({
type: "POST",
url: 'ControladorServlet',
data: {cmd: args[i], operacion: 1, ticket: ticket, iddispositivo: sesion},
success: function (response) {
var textarea = document.getElementById('respuesta');
var res = response.trim().split('\n');
if(error){//dc}
else
{
document.getElementById('respuesta').value = document.getElementById('respuesta').value + response.trim() + "\n\n";
var valor = (100) * (i + 1) / args.length;
move(valor);
if (i + 1 < args.length)
{
executeCMD(args, i + 1);
}
}
},
dataType: 'text'
});
});
}
I'm trying to ratelimit my ajax requests in order to remain within api limits. I make one request to my server which returns a list of data. From that list of data, I make a request to an api which does not allow receiving more than one request per second. How can I use setTimeout or a similar function to limit my requests?
myArray = ['1','2','3'];
function f1(){
for (var num in myArray){
$.ajax({
type: "POST",
url: "backend.php",
data: {suburbs : num},
success: function(data){
for (var item in data){
f2(data[item])
}
}
});
}
}
function f2(text) {
$.getJSON("http://example.com/test.html?" + text, null, function (data) {
console.log(data)
}
}
Just create a list of functions:
var duration = 1000; // API duration
var expectAsync = 3000; // time to wait for new functions;
var lastCall = Date.now();
var myArray = ['1','2','3'];
function queryArray() {
var fnList = [];
myArray.forEach(function(v){
fnList.push( function() { // push f1 to list;
$.ajax({
type: "POST",
url: "backend.php",
data: {suburbs : v},
success: function(data){
fnList.push(function(){ // push f2, after we get response;
for (var item in data){
f2(data[item]);
}
})
}
})
});
// here we go;
var int;
int = setInverval(function(){
if(fnList.length){
var fn = fnList.shift(); // pop first function from left;
fn();
}else{
if((Date.now() - lastCall) > expectAsync) clearInterval(int);
}
lastCall = Date.now();
}, duration);
}
setTimeout does not work like java's sleep. It is asynchronous with a callback. After the time is up, the callback function get triggered, which means that you want to put your request into the callback function.
myArray = ['1','2','3'];
function f1(){
for (var i = 0; i < myArray.length; i++){
$.ajax({
type: "POST",
url: "backend.php",
data: {suburbs : myArray[i]},
success: function(data){
for (var j = 0; j < data.length; j++){
setTimeout(function() {
f2(data[j]);
}, (i*data.length + j)*1000);
}
}
});
}
}
In the for loop, you need to use the index to determine how long you need to wait. After the request is triggered.