Delay a function execution in javascript using underscore - javascript

Libraries used : Q and underscore.
This is the following scenario in my code.
pollEngine : _.throttle(function() {
return that.fetchStatus()
.then(function(data) {
if(data) {
//keep polling until the data returned is false
return that.pollEngine();
}
else {
return;
}
});
}, 1000);
fetchStatus: function() {
var deferred = Q.defer();
$.ajax({
//code
success: function(data) {
deferred.resolve('true' or 'false' depending on data);
}
error: function() {
deferred.reject('error');
}
});
return deferred.promise;
}
This code executes first time immediately and if the data returned is true, the subsequent ajax calls are made at 1 second intervals due to throttle.
I want to delay the ajax call even first time by a few milli seconds as the server data might not be ready. But whatever code I try using delay, throttle etc. the fetchStatus function and the subsequent ajax calls are performed immediately .

Related

jquery get data from php page after every 2 secounds

I am get data from php page after every 2 secounds the data is very large when i call it once then the data comes but when i place my code in setinterval function then the data in console is not showing I place this code in setinterval function because after every 2 sec i need fresh data any idea plz share
var data_array = '';
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
},
error:function(errorMsg)
{
}
});
}, 5000);
console.log(data_array);
There's a couple of issues you have here, the main one being that you're trying to make a synchronous ajax call, and that's been deprecated. You need to handle it being an asynchronous call instead...
Put the code that you want to run every time you get new data into a function and call that function in the success callback
var data_array = ''; // this is a global variable
function getNewData() {
$.ajax({
url: "./phponline.php",
})
.done(function(res) {
data_array = res; // the global variable is updated here and accessible elsewhere
getNewDataSuccess();
})
.fail(function() {
// handle errors here
})
.always(function() {
// we've completed the call and updated the global variable, so set a timeout to make the call again
setTimeout(getNewData, 2000);
});
}
function getNewDataSuccess() {
console.log(data_array);
}
getNewData();
As I explained in the comments, using setInterval with an ajax call is a bad idea as you could end up overlapping calls if they take longer than the interval. This method makes a call, waits for the result and then uses setTimeout to make the next call instead. This way you can never make an ajax call until 2 seconds after the last one was completed.
As Muhammed Atif said in the comments, you need to place the console log inside the SetInterval function.
var data_array = '';
function handleData() {
console.log(data_array);
}
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
handleData();
},
error:function(errorMsg)
{
}
});
}, 5000);
you need to call some custom function inside ajax success of setInterval to provide the effect of response stored in data_array:
var data_array = '';
$(document).on('ready', function(event, data) {
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
updateWithData();
},
error:function(errorMsg)
{
}
});
}, 5000);
updateWithData();
});
function updateWithData(){
//use data_array to make changes on each call.
}
Your console.log should be called in the success callback or directly after the ajax call in the setInterval callback.
If you place the console.log after the setInterval, data_array will be empty because it's setted 5 seconds later.
var data_array = '';
setInterval(function () {
$.ajax({
url:"./phponline.php",
async:false,
success:function(res)
{
data_array = res;
console.log(data_array);
},
error:function(errorMsg)
{
}
});
}, 5000);

Trying to achieve asynchronous read calls on oData in SAPUI5

I am trying to achieve the asynchronous function calls for reading the odata in SAPUI5.
here is a example:
this.odataModel = new sap.ui.model.odata.ODataModel(oDataUrl, true, 'user', 'pwd');
/* data retrieving time 5sec */
function read1(){
this.odataModel.read('entity-url1',null, null, true, function(data){
console.log('success');
return data;
},
function(){ console.log('error'); });
}
/* data retrieving time 10sec */
function read2(){
this.odataModel.read('entity-url2',null, null, true, function(data){
console.log('success');
return data;
},
function(){ console.log('error'); });
}
/* data retrieving time 10sec */
function read3(){
this.odataModel.read('entity-ur3',null, null, true, function(data){
console.log('success');
return data;
},
function(){ console.log('error'); });
}
/* function calls */
var d1 = read1();
var d2 = read2();
var d3 = read3();
after this call i am trying to get the data from read3 function i am getting empty data. becuse of execution time.
How can i wait for until execution is completed.
You won't see any data because your requests are performed asynchronously! If you want to process the data you have to do this in the success callback of the model's read method. But even with a synchronous call you won't see data, as your methods read1, read2, read3 do not return the data.
You're seeing this because the sap.ui.model.odata.ODataModel.read() calls are asynchronous by default - while the read in your read1() call is being executed, the Javascript event queue is continuing processing and executing the remainder of your code. This asynchronous execution is a Good Thing, but you need to cater for it in your code.
There are a few solutions, but the easiest is to only initiate the second read once the first has executed and only initiate the third once the second has completed. You can do this by modifying your success handlers.
So, a very crude adjustment to read1():
function read1(){
this.odataModel.read('entity-url1',null, null, true, function(data){
console.log('success');
read2();
return data;
},
function(){ console.log('error'); });
}
Then, do the same for read2() and modify your caller to only call read1(). Of course, you'll need to adjust how you return the data to the caller.
A bit untidy, but I hope the above shows the gist of what I'm trying to describe.
You can use jQuery or native promise
//jQuery version
function read1() {
var promise = jQuery.Deferred();
this.odataModel.read('entity-url1', null, null, true, function(data) {
console.log('success');
promise.resolve(data);
},
function() {
console.log('error');
});
return promise;
}
var d1 = read1(); // d1 promise;
d1.then(function(data) {
console.log(data);
});

Making multiple ajax requests synchronously

Let's suppose I have some function called makeRequest(), which makes an AJAX request to a server.
Now let's suppose I am given the amount of times this request should be made, but I can't do them asynchronously but synchronously instead.
For instance, I am given the number 5, and I shall call makeRequest(), when it's done, I shall call it again, and when it's done, I shall call it again... I should end up calling it 5 times.
I'm no expert at JavaScript but I found it easy to handle asynchronous calls by the use of callbacks.
So, my makeRequest() function takes a callback argument that is to be executed when the request has succeeded.
In my previous example, I had to make the request 5 times, so the behaviour should look like:
makeRequest(function () {
makeRequest(function () {
makeRequest(function () {
makeRequest(function () {
makeRequest(function () {
});
});
});
});
});
How can I design this to behave the same for any argument given to me, be it 6, 12 or even 1?
PS: I have tried many approaches, the most common involving creating while loops that wait until a flag is set by a finished request. All of these approaches makes the browser think the script crashed and prompt the user to stop the script.
Simple, recursively call the ajax request, while keeping track of a count variable:
function makeRequest(count, finalCallback){
someAjaxCall(data, function(){
if(count > 1){
makeRequest(count - 1, finalCallback);
} else {
finalCallback && finalCallback();
}
});
}
finalCallback is a optional callback (function) that will be executed when all the requests are completed.
You can do it this way,
var i = 5; // number of calls to you function calling ajax
recurs(i); // call it initially
function recurs(count) {
makeRequest(function() {
count--; // decrement count
if (count > 1) {
recurs(count) // call function agian
}
});
}
Here I have written multiple Ajax calls using promises. This function will run synchronously. You can get the current position of response which is executed from Ajax.
var ajaxs = {
i : 0,
callback : null,
param : null,
exec_fun : function (i) {
let data_send = this.param[i];
let url = this.url;
this.promise = new Promise(function (res,rej) {
$.ajax({
url: url,
method: 'POST',
data: data_send,
dataType: 'json',
success: function(resvalidate){
res(resvalidate);
}
});
});
this.promise.then(function (resvalidate) {
let resp = resvalidate,
param = ajaxs.param,
pos = ajaxs.i,
callback_fun = ajaxs.callback_fun;
callback_fun(resp,ajaxs.i);
ajaxs.i++;
if( ajaxs.param[ajaxs.i] != undefined){
ajaxs.exec_fun(ajaxs.i);
}
});
},
each : function (url,data,inc_callback) {
this.callback_fun = inc_callback;
this.param = data;
this.url = url;
this.exec_fun(ajaxs.i);
}
};
let url = "http://localhost/dev/test_ajax.php";
let data_param = [{data : 3},{data : 1},{data : 2}];
ajaxs.each(url,data_param, function (resp,i) {
console.log(resp,i);
});

Getting undefined via ajax JSON

when I check the log from Console using chrome browser, I keep getting sideType is undefined. It is not returning data to sideType variable.
when I put console.log(sideType); in the sideGroupData() function - it work fine without problem.
Code:
function sideGroupData(GroupID) {
$.getJSON("group_data.php",{GroupID:GroupID}, function(j){
return j;
});
}
function reloadProduct(productID) {
$.post("product.php", { productID:productID }, function(data) {
var sideType = sideGroupData(123);
console.log(sideType);
});
}
reloadProduct(999);
It's because you're running your call in a closure. The ajax call is being made asynchronously, which means that your code continues moving even though you're making an ajax call:
function setVar () {
var retVal = 1;
$.ajax(..., function(data){
retVal = data; //retVal does NOT equal data yet, it's still waiting
});
return retVal; //will return 1 every time because code doesn't wait for ajax
}
var someVar = setVar(); // will be 1
If you want to return that value, include a callback function to run when the data is returned, and run it with the data supplied, like so:
function sideGroupData(GroupID, callback){
$.getJSON('group_data.php', {GroupID: GroupID}, callback);
}
function reloadProduct(productID) {
$.post("product.php", { productID:productID }, function(data) {
sideGroupData(123, function(sideType){
console.log(sideType);
});
});
}
or, just make the call inside the function itself:
function reloadProduct(productID, groupId) {
var prod, sideType;
$.post("product.php", { productID:productID }, function(data) {
prod = data;
$.getJSON('group_data.php', {GroupID: groupId}, function(json){
sideType = json;
// you now have access to both 'prod' and 'sideType', do work here
});
});
}
the sidegroupdata() function call will return immediately - it'll trigger the ajax request and keep on executing. That means sideType is being assigned a null value, because sideGroupData doesn't actually explicitly return anything after the ajax call section.
Is there any reason you're doing an ajax request WITHIN an ajax request? Wouldn't it make more sense to modify the product.php page to return a data structure containing both that product ID AND the 'sidegroupdata' included in a single response?

jQuery AJAX polling for JSON response, handling based on AJAX result or JSON content

I'm a novice-to-intermediate JavaScript/jQuery programmer, so concrete/executable examples would be very much appreciated.
My project requires using AJAX to poll a URL that returns JSON containing either content to be added to the DOM, or a message { "status" : "pending" } that indicates that the backend is still working on generating a JSON response with the content. The idea is that the first request to the URL triggers the backend to start building a JSON response (which is then cached), and subsequent calls check to see if this JSON is ready (in which case it's provided).
In my script, I need to poll this URL at 15-second intervals up to 1:30 mins., and do the following:
If the AJAX request results in an error, terminate the script.
If the AJAX request results in success, and the JSON content contains { "status" : "pending" }, continue polling.
If the AJAX request results in success, and the JSON content contains usable content (i.e. any valid response other than { "status" : "pending" }), then display that content, stop polling and terminate the script.
I've tried a few approaches with limited success, but I get the sense that they're all messier than they need to be. Here's a skeletal function I've used with success to make a single AJAX request at a time, which does its job if I get usable content from the JSON response:
// make the AJAX request
function ajax_request() {
$.ajax({
url: JSON_URL, // JSON_URL is a global variable
dataType: 'json',
error: function(xhr_data) {
// terminate the script
},
success: function(xhr_data) {
if (xhr_data.status == 'pending') {
// continue polling
} else {
success(xhr_data);
}
},
contentType: 'application/json'
});
}
However, this function currently does nothing unless it receives a valid JSON response containing usable content.
I'm not sure what to do on the lines that are just comments. I suspect that another function should handle the polling, and call ajax_request() as needed, but I don't know the most elegant way for ajax_request() to communicate its results back to the polling function so that it can respond appropriately.
Any help is very much appreciated! Please let me know if I can provide any more information. Thanks!
You could use a simple timeout to recursively call ajax_request.
success: function(xhr_data) {
console.log(xhr_data);
if (xhr_data.status == 'pending') {
setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
} else {
success(xhr_data);
}
}
Stick a counter check around that line and you've got a max number of polls.
if (xhr_data.status == 'pending') {
if (cnt < 6) {
cnt++;
setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
}
}
You don't need to do anything in your error function unless you want to put an alert up or something. the simple fact that it error will prevent the success function from being called and possibly triggering another poll.
thank you very much for the function. It is a little bit buggy, but here is the fix. roosteronacid's answer doesn't stop after reaching the 100%, because there is wrong usage of the clearInterval function.
Here is a working function:
$(function ()
{
var statusElement = $("#status");
// this function will run each 1000 ms until stopped with clearInterval()
var i = setInterval(function ()
{
$.ajax(
{
success: function (json)
{
// progress from 1-100
statusElement.text(json.progress + "%");
// when the worker process is done (reached 100%), stop execution
if (json.progress == 100) clearInterval(i);
},
error: function ()
{
// on error, stop execution
clearInterval(i);
}
});
}, 1000);
});
The clearInterval() function is becomming the interval id as parameter and then everything is fine ;-)
Cheers
Nik
Off the top of my head:
$(function ()
{
// reference cache to speed up the process of querying for the status element
var statusElement = $("#status");
// this function will run each 1000 ms until stopped with clearInterval()
var i = setInterval(function ()
{
$.ajax(
{
success: function (json)
{
// progress from 1-100
statusElement.text(json.progress + "%");
// when the worker process is done (reached 100%), stop execution
if (json.progress == 100) i.clearInterval();
},
error: function ()
{
// on error, stop execution
i.clearInterval();
}
});
}, 1000);
});
You can use javascript setInterval function to load the contents each and every 5 sec.
var auto= $('#content'), refreshed_content;
refreshed_content = setInterval(function(){
auto.fadeOut('slow').load("result.php).fadeIn("slow");},
3000);
For your reference-
Auto refresh div content every 3 sec

Categories

Resources