Status on AJAX request hanging - javascript

I have a button when clicked send an ajax request to fire a PHP function which takes a while for it to complete. I have a timed function that checks the status of the first function. The problem being is that these two have a status of pending, and the function that is on a timer seems to freeze until the first function is completed.
$(document).ready(function() {
var ripstatus;
var intervalID;
$("#ripe_start").click(function() {
if (ripstatus) return;
console.log('started');
$("#ripe_start").addClass("ripe_start_activate");
$("#ripe_start").removeClass("ripe_clickable");
getid('ripe_start').innerHTML = 'Initializing';
ripe_getstatus();
intervalID = window.setInterval(ripe_getstatus(), 500);
})
function ripe_getstatus() {
console.log('getting number ' + ripstatus);
$.get('./?ajax=1&callfunction=returnNumScan', function(data) {
getid('ripe_start').innerHTML = data + ' file(s) left to organize';
});
}
$('#ripe_start').on('transitionend webkitTransitionEnd oTransitionEnd', function() {
console.log('ended');
doextorg();
});
function doextorg() {
if (ripstatus == 1) return;
console.log('exc org processing ' + ripstatus);
ripstatus = 1;
$.ajax({
url: "./?ajax=1&callfunction=organize",
context: document.body
}).done(function(output) {
clearinterval(intervalID);
$("#ripe_start").removeClass("ripe_start_activate");
getid('ripe_start').innerHTML = 'Complete ' + output + ' File(s) organized';
});
} //end function
});

Related

Looping array that generates ajax call, i need the first call to finish before next one starts

Simply i just loop an array, and submit data with get in the loops, but i runs so fast that the server stops running. I mini Ddos myself doing this. How i can i make the loop wait until the calls finish, perhaps adding a 1 sek break between loops
$( document ).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
//Gets data from input field
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
array_urls.forEach(function(entry) {
var request = $.get("action.php",
{
add_link: "1",
url: encodeURIComponent(entry.trim()),
},
function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1)
{
success++;
total++;
//update fields removed in this post
$("#success_count").html((success));
$("#total_count").html((total));
}
if (data == 2) {
error++;
total++;
//update fields removed in this post
$("#error_count").html((error));
$("#total_count").html((total));
}
});
promiss.push(request);
});
$.when.apply(null, promiss).done(function(){
//do something when done;
});
return false;
});
You could use recursive function to achieve this.
Example
$(document).on("submit", "#add_links", function() {
var error = 0;
var success = 0;
var total = 0;
var new_urls = $("#new_urls").val();
var array_urls = new_urls.split("\n");
var promiss = [];
let index = 0;
function sendAjaxCall() {
if(count >= array_urls.length) return;
var request = $.get(
"action.php",
{
add_link: "1",
url: encodeURIComponent(array_urls[index].trim())
},
function(data, status) {
console.log("Data: " + data + "\nStatus: " + status);
if (data == 1) {
success++;
total++;
$("#success_count").html(success);
$("#total_count").html(total);
}
if (data == 2) {
error++;
total++;
$("#error_count").html(error);
$("#total_count").html(total);
}
count++;
promiss.push(request);
sendAjaxCall();
}
);
}
$.when.apply(null, promiss).done(function() {
$("#close_bug_reportwindow").html(
"Import done, close tab by clicking here"
);
$("#close_icon").html('(<i class="fas fa-times"></i>)');
$("#progress").remove();
});
return false;
});

Multiple calls to Ajax instead of once

I have the following code which works fine for most cases, but the problem I am having is on mouse over . After you hover for 10 sec the content expands and then calls ajax. The Ajax is making calls 5 times instead of just once.
I am not sure why its keep calling 5 times. Can someone help me fix this so ajax call runs only once?
Here is my code snippet below and the full working fiddle demo is here
$(".previewCard-content").hide();
var timeo = null;
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null) {
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});
Mouse hover events happen every time the mouse moves over the element. You need is to have a boolean which checks if you have sent the AJAX Request or not, and if it hasn't send the AJAX request, else ignore the event.
$(".previewCard-content").hide();
var timeo = null;
var ajaxSent = false
$("body").on("mouseenter", ".previewCard-showhide", function() { // Use rather mouseenter!
var $that = $(this); // Store the `this` reference
clearTimeout(timeo); // Clear existent timeout on m.Enter
timeo = setTimeout(function() { // Before setting a new one
$that.hide().closest('p').next(".previewCard-content").slideDown("slow");
/**************** AJAX CALL********************/
var LinkTextVal = $that.closest('.previewCard-b').find('.previewCardPageLink').text();
console.log(" LinkTextVal " + LinkTextVal);
var descPageName = LinkTextVal + ' | About';
if ($('#userID').val() !== '' && $('#userID').val() !== undefined && $('#userID').val() !== null && !ajaxSent) {
ajaxSent = true;
$.ajax({
url: '/localhost/biz/actions/searchBookmark' + '?cachestop=' + nocache,
type: "get",
data: {
bookmarkName: descPageName
},
success: function(response) {
if (response === true) {
$that.parents('.previewCard-b').find('.save a').addClass('saved');
$that.parents('.previewCard-b').find('.save a').addClass('active');
$that.parents('.previewCard-b').find('.save a').find(".action-text").text("Saved");
}
},
error: function(e) {
console.log('Unable to check if a bookmark exists for the user.');
}
});
}
/***************** END AJaX/SAVE BUTTON ************/
}, 1000);
}).on("mouseleave", ".previewCard-showhide", function() { // mouse leaves? Clear the timeout again!
clearTimeout(timeo);
});
$(".close-btn").on("click", function() {
var $itemB = $(that).closest(".previewCard-b");
$itemB.find(".previewCard-content").slideUp();
$itemB.find(".previewCard-showhide").show();
});

Understanding chaining of sequential asynchronous operations using jquery deferred and then

I have been trying to wrap my head around jquery deferred and then functions. As I gather from jQuery then documentation, the then function sends the return value of the callback to the next then handler if they are so chained. Given that, why is my code not working as expected?
function log(message) {
var d = new Date();
$('#output').append('<div>' + d.getSeconds() + '.' + d.getMilliseconds() + ': ' + message + '</div>');
}
function asyncWait(millis) {
var dfd = $.Deferred();
setTimeout(function () {
var d = new Date();
log('done waiting for ' + millis + 'ms');
dfd.resolve(millis);
}, millis);
return dfd.promise();
}
function startTest0() {
return asyncWait(1000).then(asyncWait).then(asyncWait).then(asyncWait).done(function () {
log('all done, 4 times');
});
}
function startTest() {
asyncWait(500).then(function () {
return asyncwait(1000);
}).then(function () {
return asyncWait(1500);
}).then(function () {
return asyncWait(2000);
}).done(function () {
log('all done');
});
}
log('welcome');
log('starting test ...');
startTest0().done(function() { log('starting the second test'); startTest(); });
JS Fiddle here: Sample code. I was expecting a similar behavior in both tests but something eludes me. What am I missing?
Thanks in advance!
EDIT: See an updated DEMO where I am trying to chain the async operations to start after the previous one is done.
Except for one typo (asyncwait instead of asyncWait) your code works. Check below.
function log(message) {
var d = new Date();
$('#output').append('<div>' + d.getSeconds() + '.' + d.getMilliseconds() + ': ' + message + '</div>');
}
function asyncWait(millis) {
var dfd = $.Deferred();
setTimeout(function () {
var d = new Date();
log('done waiting for ' + millis + 'ms');
dfd.resolve(millis);
}, millis);
return dfd.promise();
}
function startTest0() {
return asyncWait(1000).then(asyncWait).then(asyncWait).then(asyncWait).done(function () {
log('all done, 4 times');
});
}
function startTest() {
asyncWait(500).then(function () {
return asyncWait(1000);
}).then(function () {
return asyncWait(1500);
}).then(function () {
return asyncWait(2000);
}).done(function () {
log('all done');
});
}
log('welcome');
log('starting test ...');
startTest0().done(function() { log('starting the second test'); startTest(); });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>
Lesson to learn: Put any JS code through jshint before and after you fix bugs.
As i can see here, you are calling startTest0 function returning its promise object and calling then callback without returning new times into next then callback. I modified your startTest() into this :
function startTest() {
return asyncWait(500).then(function () {
asyncWait(1000);
return 1500; // here we pass to the next then
}).then(function (ms) { // ms here we got 1500
asyncWait(ms);
return 2000; // here we pass to the next then
}).then(function (ms) { // ms here we got 2000
asyncWait(ms)
return asyncWait(2500);
}).done(function () {
log('all done');
});
}
DEMO

How to do ajax request and html element update in background?

I have html form with three elements - buttons start and stop and text area. Once start button is pressed, I would like to do multiple ajax requests and once result is received to update the text area, once stop is pressed, processing of ajax requests should be stopped.
I tried to do something like below:
$(document).ready(function(){
var inProgress = false;
$("#stop").click(function() {
inProgress = false;
});
$("#start").click(function() {
inProgress = true;
while (inProgress) {
$('#textarea').html($('#textarea').val()+sometext+'\n');
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
});
}
});
But it doesn't work as expected - browser tab hangs. What is wrong with my code?
Don't use while loop. You should do it in an asynchoronous way: At the end of .done function, put another asynchronous ajax call.
// other stuff goes here
function doRequest() {
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
if (inProgress) doRequest();
});
}
$("#start").click(function() {
inProgress = true;
$('#textarea').html($('#textarea').val()+sometext+'\n');
doRequest();
});
Well, since $.ajax is asynchronous by default, you are making a loooot of XHR (ajax calls) ! ;-)
Try this :
$(document).ready(function(){
var inProgress = false;
$("#stop").click(function() {
inProgress = false;
});
$("#start").click(function() {
inProgress = true;
refresh();
});
function refresh() {
$('#textarea').html($('#textarea').val()+sometext+'\n');
$.ajax({url: 'http://example.com'})
.done(function(data, textStatus, jqXHR) {
$('#textarea').html($('#textarea').val()+someresult+'\n');
if (inProgress) refresh();
});
}
});
Probably because the browser is busy doing requests and it cannot listen other events. Try to put the code in a function and then use the
setTimeout( function_reference, timeoutMillis );
with a reasonable timeout.
See this code as an example:
function startTime() {
var today = new Date();
var h = today.getHours();
var m = today.getMinutes();
var s = today.getSeconds();
// add a zero in front of numbers<10
m = checkTime(m);
s = checkTime(s);
document.getElementById("txt").innerHTML = h+ ":" + m + ":" + s;
t = setTimeout(function(){startTime()}, 500);
}
function checkTime(i) {
if (i<10) {
i = "0" + i;
}
return i;
}

JS Wait till page Loads, Unless 5 seconds have passed then start timer (alter current .js)

The below code is a timer for my site's ads. The way its setup now it waits for the page to load fully before starting the timer. What I would like to do is to Alter this slightly to only wait 5 seconds, if the page has not finished loading by then just go ahead and start the timer. I have no idea how to do this at all.
$(document).ready(function () {
ptcevolution_surfer();
});
function showadbar(error) {
$("#pgl").removeAttr("onload");
if (error == '') {
$(".adwait").fadeOut(1000, function () {
$("#surfbar").html('<div class="progressbar" id="progress"><div id="progressbar"></div></div>');
$("#progressbar").link2progress(secs, function () {
endprogress('');
});
});
} else {
$(".adwait").fadeOut(1000, function () {
$("#surfbar").html("<div class='errorbox'>" + error + "</div>");
$(".errorbox").fadeIn(1000);
});
}
}
/* End Surf Bar */
function endprogress(masterkey) {
if (masterkey == '') {
$("#surfbar").fadeOut('slow', function () {
$("#vnumbers").fadeIn('slow');
});
return false;
} else {
$("#vnumbers").fadeOut('slow', function () {
$(this).remove();
$("#surfbar").fadeIn('slow');
});
}
$("#surfbar").html("Please wait...");
var dataString = 'action=validate&t=' + adtk + '&masterkey=' + masterkey;
$.ajax({
type: "POST",
url: "index.php?view=surfer&",
data: dataString,
success: function (msg) {
if (msg == 'ok') {
$("#surfbar").html("<div class='successbox'>" + adcredited + "</div>");
$(".successbox").fadeIn('slow');
if (adtk == 'YWRtaW5hZHZlcnRpc2VtZW50') {
window.opener.hideAdminAdvertisement();
} else {
window.opener.hideAdvertisement(adtk);
}
return false;
} else {
$("#surfbar").html("<div class='errorbox'>" + msg + "</div>");
$(".errorbox").fadeIn('slow');
}
}
});
}
function ptcevolution_surfer() {
if (top != self) {
try {
top.location = self.location;
} catch (err) {
self.location = '/FrameDenied.aspx';
}
}
$("#surfbar").html("<div class='adwait'>" + adwait + "</div>");
}
By your use of $, I'm going to assume jQuery
var __init = (function () {
var initialised = 0; // set a flag, I've hidden this inside scope
return function () { // initialisation function
if (initialised) return; // do nothing if initialised
initialised = 1; // set initialised flag
ptcevolution_surfer(); // do whatever
};
}()); // self-invocation generates the function with scoped var
window.setTimeout(__init, 5e3); // 5 seconds
$(__init); // on page ready
Now what happens? The first time the function is fired, it prevents itself from being fired a second time, then starts off whatever you want done.

Categories