jQuery deferred queue in for loop - javascript

I have the following function:
function getData(a,url) {
var deferreds = [];
var i = 1;
for (i = 1; i <= a.length; i++) {
var count = i;
var back = a[i]['link'];
var path = "http://example.com";
deferreds.push(
$.ajax({
url:path,
data:{back:back,link:url},
type:"POST",
async: true,
delay: count
}).done(function(data) {
//success function here
}));
}
return deferreds;
}
My question is how to make this script to run a queue, for example I have 2000 requests, how to put them in a queue of 100 one by one?

Maybe in this way (Of course is a simplification)
var completed = 0;
var limit_simultaneous = 100;
var total_requests = 2134 // Assign your var
function send_block() {
for (i = 0; i < limit_simultaneous; i++) {
$.ajax({
url:path,
data:{back:back,link:url},
type:"POST",
async: true,
}).done(function(data) {
completed++;
send_next_block();
//success function here
}));
}
}
function send_next_block()
{
if (completed == limit_simultaneous && total_requests > 0) {
total_requests = total_requests - completed;
if (total_requests < limit_simultaneous) {
limit_simultaneous = total_requests;
}
completed = 0;
// Fire again
send_block(); // Send another 100
}
}
I hope it helps.
EDIT Edit to take account about the total requests. Maybe is not a working code, but it is the idea.

Related

Deferred objects with multiple getJSON calls that depend on each other

I am making 3 get JSON calls in myFunction() that gets called on a button click. 2 of these getJSONs depend on each other for their execution. It basically parses through 10 web pages and collects some data. With this data it will go to another page and collect some other data. I want to display "DONE" at the end of myFunction so the user knows that we have finally got all data and the search operation is complete. However these calls, I think, are asynchronous, so I use deferred objects. But even though I pass all calls to $.when.apply(call1,call2,call3), it displays the "DONE" before any data is printed on the console. Once it prints "DONE", then it starts to print the results. How can I modify my code so that I would be able to display "DONE" only when myFunction has ran completely for all 10 pages and has printed all data on the console.
var call1 = [];
var call2 = [];
var call3 = [];
function myFunction() {
data3 = [];
url = ''; // some URL here
call3.push($.getJSON(url, function(data4) {
data3 = data4;
}));
for (var page = 1; page < 10; page++) {
(function(page) {
url = 'http://example.com/' + page;
call1.push($.getJSON(url, function(data1) {
for (var num = 0; num < data1.standings.results.length; num++) {
(function(num) {
url = 'http://example.com/' + data1.entry[num];
call2.push($.getJSON(url, function(data2) {
for (var i = 0; i < 15; i++) {
(function(i) {
console.log(data3.ele[(data2.p[i].element) - 1].x);
return;
}
})(i);
}
})
);
})(num);
}
})
);
})(page);
};
$.when.apply(call1, call2, call3).then(function() {
console.log("DONE");
});
}
I was finally able to solve this problem. As mentioned in the comments, we need to chain various promises and the function structure should match the structure of the when command. So, in the function as call1 was pushed first, I need to call the when command for call1 and then nest the subsequent commands and so on.
var call1 = [];
var call2 = [];
var call3 = [];
function myFunction() {
data3 = [];
url = ''; // some URL here
call3.push($.getJSON(url, function(data4) {
data3 = data4;
}));
for (var page = 1; page < 10; page++) {
(function(page) {
url = 'http://example.com/' + page;
call1.push($.getJSON(url, function(data1) {
for (var num = 0; num < data1.standings.results.length; num++) {
(function(num) {
url = 'http://example.com/' + data1.entry[num];
call2.push($.getJSON(url, function(data2) {
for (var i = 0; i < 15; i++) {
(function(i) {
console.log(data3.ele[(data2.p[i].element) - 1].x);
return;
}
})(i);
}
})
);
})(num);
}
})
);
})(page);
};
$.when.apply($, call1).then(function(){
$.when.apply($, call2).then(function(){
document.getElementsByName('output')[0].value+="Search Completed"+'\r\n';
});
});
}

Uncaught SyntaxError: Illegal break statement within ajax

Here i'm trying to break out of a loop within an nested statement as per various questions i've seen in stackoverflow none seems to work right now code is below.
for (var i = 0; (i < 10); i++) {
var URL = "http://www.goibibo.com/hotels/search-data/?app_id=1c1cc02b&app_key=54829b227c915bd0267dec660271fa87&vcid=4675090819370906231&ci=20170720&co=20170721&r=1-1_0&pid=" + i
$.ajax({
url: URL,
type: "GET",
success: function (data) {
shareInfoLen = Object.keys(data["4675090819370906231"]).length;
if (shareInfoLen > 0) {
alert('On Process');
}
else if (shareInfoLen === 0){
alert('Closed');
break;
}
},
error: function (reponse) { }
});
}
I have used return false over break i used condition (i < 10 && j == true) and return j = false on else if condition instead of break, as i will be using infinite loop like for(var i = 0; ; i++) i need to break out of the loop if the array is 0.
Working code here.
var result = true;
for (var i = 0; i < 5; i++) {
var URL = "https://www.goibibo.com/hotels/search-data/?app_id=1c1cc02b&app_key=54829b227c915bd0267dec660271fa87&vcid=4675090819370906231&ci=20170720&co=20170721&r=1-1_0&pid=" + i
$.ajax({
url: URL,
type: "GET",
success: function (data) {
if(result){
shareInfoLen = Object.keys(data["4675090819370906231"]).length;
if (shareInfoLen > 0) {
alert('On Process');
}
else if (shareInfoLen === 0){
alert('Closed');
result = false;
}
}
},
error: function (reponse) { }
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

making multiple ajax calls within a for loop

I'm a relative newbie to javascript and I'm trying to make multiple ajax calls within a for loop. It loops through the elements of an array using a different url for an ajax call each time it goes through the loop. The problem is that the value of the variable 'test' is always equal to "condition4". I'm used to other languages where the value of 'test' would be "condition1", then "condition2" etc as it goes through the for loop. Here is a simplified version of my code:
var myData = [];
var cnt = 0;
var link;
var myCounter = 0;
var myArray = ["condition1", "condition2", "condition3", "condition4"];
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[myCounter];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
}
function GetJSON(callback) {
$.ajax({
url: link,
type: 'GET',
dataType: 'json',
success: function (results) {
callback(results);
}
});
}
I think you can solve this issue by sending and receiving myCounter value to server
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
$.ajax({
url: link,
type: 'GET',
dataType: 'json',
data: { myCounter: myCounter}
success: function(results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = results.data[i].myCounter
myData[cnt] = {
"id": id,
"test": test
};
cnt++;
}
}
});
}
When you are executing the loop, it attaches the myCounter reference. Then, due to the async task, when it finishes and call 'myCounter', it has already achieved the number 4. So, when it call 'myCounter', it is 4. To isolate the scope, you need to create a new scope every iteration and isolating each value of 'myCounter'
for (x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
//IIFE
(function() {
var ownCounter = myCounter; //Isolating counter
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[ownCounter];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
})();
}
Or...
for (let x = 0; x < myArray.length; x++) {
link = "https://test.com/" + myArray[x];
myCounter = x;
GetJSON(function (results) {
for (i = 0; i < results.data.length; i++) {
var id = results.data[i].identifier;
var test = myArray[x];
myData[cnt] = { "id": id, "test": test };
cnt++;
}
});
}

JavaScript ajax success break and continue not working

Hey guys so am testing this cracker am working on via localhost to see if i can do it really since am bored and want to do something so i thought about this but may i ask why break and continue arnt working its a for loop isnt it?, So it should work.
Edit:
Forgot to mention that the code doesnt even work when i added the break and continue.
Any help is great thanks.
function doTest() {
var html_next;
var user_l = document.getElementById("users");
var pass_l = document.getElementById("pass");
if (user_l.value == "") {
alert("The username field cant be empty!")
} else if (pass_l.value == "") {
alert("The password field cant be empty!")
}
var message = document.getElementById('status_1');
var user_l_s = user_l.value.split("\n");
var pass_l_s = pass_l.value.split("\n");
for (var i = 0; i < user_l_s.length; i++) {
num_users++;
for (var j = 0; j < pass_l_s.length; j++) {
$.ajax({
url: 'posttest.php',
type: 'GET',
data: {'users': user_l_s[i], 'pass': pass_l_s[j]},
dataType: 'text',
async: false,
success: (function (i, j) {
return function (response) {
html_next = response;
if (html_next.indexOf("Failed") > -1) {
continue;
} else if (html_next.indexOf("Cracked") > -1) {
break;
} else if (html_next.indexOf("DELETED") > -1) {
break;
}
}
})(i, j),
beforeSend: function () {
message.innerHTML = "Cracking Test...";
}
});
}
}
message.innerHTML = "Done...";
}
It is because you are sending an Async request to your server. Which means your server is handling multiple requests and it is not necessary that every request gets responded to in the same time.
What you are looking for is sequential code that can process your data all at once.
You should try async:false and then try
You have to use success callbacks, you just need to use other logic. Instead for loops, call to a function when the ajax success is complete. This function have to register the changes and, if necessary, stop or keep working.
Here is an example that I used with another SO user but the logic and the idea are the appropriate. Instead of using loops, we wait for each success callback to keep working.
var MyApp = {
Scripts: {
ToLoad: [
'/path/to/script1.js',
'/path/to/script2.js',
'/path/to/script3.js'
],
Loaded: 0
},
DoTheJob: function(){
if( this.Scripts.ToLoad.length == this.Scripts.Loaded ) {
// do some stuff
return;
}
$.getScript(this.Scripts.ToLoad[this.Scripts.Loaded], function(){
MyApp.Scripts.Loaded++;
MyApp.DoTheJob();
});
}
};
$(function(){
MyApp.DoTheJob();
});
Here is the jsFiddle
This should do it..
You can even try it out with async = true
I think so it should work with it too
function doTest() {
var html_next;
var user_l = document.getElementById("users");
var pass_l = document.getElementById("pass");
if (user_l.value == "") {
alert("The username field cant be empty!")
} else if (pass_l.value == "") {
alert("The password field cant be empty!")
}
var message = document.getElementById('status_1');
var user_l_s = user_l.value.split("\n");
var pass_l_s = pass_l.value.split("\n");
for (var i = 0; i < user_l_s.length; i++) {
num_users++;
function makeReq(pass_l_s, index) {
var index = index || 0;
$.ajax({
url: 'posttest.php',
type: 'GET',
data: {
'users': user_l_s[i],
'pass': pass_l_s[index]
},
dataType: 'text',
async: false,
success: (function(i, index) {
return function(response) {
html_next = response;
if (html_next.indexOf("Failed") > -1) {
index += 1
if (index < pass_l_s.length)
makeReq(pass_l_s, index)
// continue;
} else if (html_next.indexOf("Cracked") > -1) {
// break;
} else if (html_next.indexOf("DELETED") > -1) {
// break;
}
}
})(i, index),
beforeSend: function() {
message.innerHTML = "Cracking Test...";
}
});
}
makeReq(pass_l_s)
}
message.innerHTML = "Done...";
}

confusing javascript setinterval, loop and jquery ajax load priorities

straight to the point
i have the following javascript and jquery code which update some checked rowsand do some stuff on each datatables row. here is my code:
function checkUpdate(){
setInterval(function(){
var listLength = updateList.length;
if(listLength > 0){
for(var r=0; r<listLength; r++){
// console.log(r)
var clID = updateList[r];
// console.log(clID)
var rRow = $('#dataTable tbody tr').find('td[data-clientid="'+clID+'"]').parent('tr');
// console.log(rRow)
var rRowIndex = rRow.index();
// console.log(rRowIndex)
var rRowDataIndex = oTable.fnGetPosition(rRow[0]);
console.log(rRowDataIndex)
$.ajax({
url: '/cgi-bin/if-Clients-list.jpl',
data: 'session=' + recievedSession + '&clientid=' + clID + '&outputformat=json',
dataType: 'json',
success: function(rowData){
// console.log(rowData)
var newRow = [];
var newOrderedRow = [];
console.log(rRowDataIndex)
newRow.push(rRowDataIndex+1, "");
for (var title in rowData[0]){
newRow.push(rowData[0][title]);
}
console.log(newRow)
},
});
};
}
},2000)
};
here is the problem:
after $.ajax() call, rRowDataIndex variable does not update or it updates but there is a problem in scopes and priorities that i couldn't understand
if i check 2 rows or more all the console.log(newRow)'s first elements will be the same
can anyone help me?
PS. i can nor present any code on web
thanks every body
You need to wrap the AJAX call in a closure to capture the value of rRowDataIndex each time through the loop.
function checkUpdate() {
setInterval(function () {
var listLength = updateList.length;
if (listLength > 0) {
for (var r = 0; r < listLength; r++) {
// console.log(r)
var clID = updateList[r];
// console.log(clID)
var rRow = $('#dataTable tbody tr').find('td[data-clientid="' + clID + '"]').parent('tr');
// console.log(rRow)
var rRowIndex = rRow.index();
// console.log(rRowIndex)
var rRowDataIndex = oTable.fnGetPosition(rRow[0]);
console.log(rRowDataIndex)
(function (rRowDataIndex) {
$.ajax({
url: '/cgi-bin/if-Clients-list.jpl',
data: 'session=' + recievedSession + '&clientid=' + clID + '&outputformat=json',
dataType: 'json',
success: function (rowData) {
// console.log(rowData)
var newRow = [];
var newOrderedRow = [];
console.log(rRowDataIndex)
newRow.push(rRowDataIndex + 1, "");
for (var title in rowData[0]) {
newRow.push(rowData[0][title]);
}
console.log(newRow)
},
});
})(rRowDataIndex);
};
}
}, 2000);
}

Categories

Resources