How to lock AJAX functions from overlapping? - javascript

I've got one function checkEvery15Seconds that runs every 15 seconds. It checks to see if new comments have been added to a page.
I've got a form that submits a new comment once the submit button is pressed, then displays the new comment on the page.
In the process of adding a new comment checkEvery15Seconds is querying the database at the same time, so I end up with duplicate comments on the page (not in the database though, this is purely a JavaScript issue).
How can I get my "submitComment" function to stop checkEvery15Seconds and restart it after the "submitComment" function has finished executing?

add a boolean called somewhat suspend15sCheck in a scope which is accessible by both functions. enable it while adding the comment and afterwards set it to false again.
in your 15sCheck-function you first have to check if you are allowed to check :-)
var suspend15sCheck = false;
function addComment()
{
suspend15sCheck = true;
// add comment on base of form data
suspend15sCheck = false;
}
function myTimer()
{
if(suspend15sCheck === false)
{
// add comments via ajax request
// remember to check if the comments who will be added already exist :-)
}
}

Simplest solution: use a flagging variable that you turn on and off. The first line of your "checkEvery15Seconds" function reads: if (!global_checkingEvery15Seconds) return;
Just set that variable (whatever you name it, global or object-bound) to true when you want the checking turned on, and off when you don't.

You'll need a status variable to indicate the current state of the comment ajax request
var requestComments = false;
if(requestComments === false) {
requestComments = true;
// make ajax request
// on ajax success/fail
requestComments = false;
}

Wrap it up in an object that allows other functions to set start/stop flags on it.
function My15SecondsObj() {
var objSelf = this;
//
this.run();
}
My15SecondsObj.Paused = false;
My15SecondsObj.prototype.run= function() {
if (!Paused)
{
// Do your call here
}
var _this = this;
setTimeout(function() { _this.run(); }, 15000);
}
Now when you want to use this object, just do
var myObj = new My15SecondsObj();
and when you want to pause it,
myObj.Paused = true;
and start it again by doing:
myObj.Paused = false;
Add some events if you want to get really crazy, so that other objects can subscribe to notifications about when the database updates have succeeded, etc...

Related

Why doesn't Javascript execute the code in sequence?

I have this simple function
function getArticles(page){
page = page || 1;
loading = false;
var articlesCache = getArticlesCache(page);
if(articlesCache){
articles = articlesCache.data;
}else{
make a request and then save the cache;
}
loading = false;
pageAttr = {
currentPage : articlesCache.current_page
lastPage : articlesCache;last_page
}
}
If I do this, loading initializes as false and pageAttr tries to create the property with articlesCache, which doesn't exist yet.
Here is the thing, loading and pageAttr run before the if/else. I know I can put this code inside the if/else , but I do not think it is good, because I'm going to make twice which I can do once. So, how do I make the code run in sequence like in PHP and others programming languanges?
If you have access to the getArticlesCache function, you could modify it to fire a callback when finished.
function getArticlesCache(page, callbackFunction){
//your existing code.
callbackFunction();
}
var articlesCache = getArticlesCache(page, function() {
//code to execute when getArticlesCache is Finished...
alert( 'getArticlesCache is Finished!' );
});
Read more: http://mrbool.com/callback-functions-in-javascript/28614#ixzz46PNJgXyH
Javascript is fire the n-steps functions asynchronously.
I suggest you to read this posts:
https://developer.mozilla.org/en-US/Learn/Getting_started_with_the_web/JavaScript_basics
https://developer.mozilla.org/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

Send setTimeout name, element id, and time as parameters of a function?

This is probably something really obvious, but I've searched around and tried a few things, and can't get it to work, so maybe someone can point out my error here.
I have a setTimeout that I will end up using over and over (and I know there is the setinterval, but I actually need to control when the timer starts and stops, and whether it starts again each time). Anyway, I figured if I'm writing it over and over, I should be able to use a function and pass it the parameters needed.
if ($('#selectRole').val() === 'Dispatch') {
//show Add Notes button
var funcAddNotesTimer = function(timerName,buttonName, timeToHide) {
console.log(timerName);
console.log(timeToHide / 1000);
timerName = setTimeout(function() {
$('buttonName').show();
}, timeToHide);
};
funcAddNotesTimer('addNotesTimer', '#disAddNotes', 30000);
I'm trying to set the timer function name to 'addNotesTimer', and when the timer is up I want to show the button with id #disAddNotes, and I want the timer to run for 30000 msec.
To me, what I have looks right, but I never get anything in my console log, so I don't think it's even getting into the function.
What am I doing wrong here?
I dont think its possible to use a string argument as the name of setTimeOut
Heres how you could approach it
// var timer = null; // dont really need that
var funcAddNotesTimer = function(buttonName, timeToHide) {
var timerName = setTimeout(function() {
//$('buttonName').show();
$(buttonName).show(); // buttonName is already a string so no need to add quotes around it.
}, timeToHide);
return timerName;
};
if ($('#selectRole').val() === 'Dispatch') {
var timer = funcAddNotesTimer('#disAddNotes', 30000);
// do something with timer
}
when you don't see any output in the console the reason must be something else(e.g. there is a bracket missing at the end of the code)
To set a variable with a dynamic name use the subscript-notation:
window[timerName] = setTimeout(/**/);
it will set a global variable named addNotesTimer.
As you currently do it you're simply overwriting the argument passed to the function.
Summary:
if ($('#selectRole').val() === 'Dispatch') {
//show Add Notes button
var funcAddNotesTimer = function(timerName,buttonName, timeToHide) {
console.log(timerName);
console.log(timeToHide / 1000);
window[timerName] = setTimeout(function() {
$(buttonName).show();
}, timeToHide);
};
funcAddNotesTimer('addNotesTimer', '#disAddNotes', 5000);
}

Proper javascript functions structure

I'm getting data from my firebase
//user balance check
var balanceRef = new Firebase('https://****.firebaseIO.com/arcade/grabbit/'+category+'/'+brand+'/'+gameId+'/'+'activePlayers'+'/'+userId+'/');
Here's the function that gets the data
//check user balance
function checkBalance(){
balanceRef.on('value', function(snapshot) {
if(snapshot.val()=== null){
mLeft=0
} else{
mLeft=snapshot.val().tokensLeft
}
return mLeft
})
}
When the user clicks a button I 1st check their balance
$('#grabbit').click(function() {
//call checkBalance function on click
var myTokensLeft=checkBalance();
});
the problem here is it's returning the function value as NaN or undefined
I've tested repeated, the function does return a value. Why can't It pick up the value on click? Am I doing something wrong with the structure. I'm very new to javascript
balanceRef.on looks like an async function to me, which is why you won't get a return value.
try something like this:
//check user balance
function checkBalance(callback){
balanceRef.on('value', function(snapshot) {
if(snapshot.val()=== null){
mLeft=0
} else{
mLeft=snapshot.val().tokensLeft
}
callback(mLeft);
})
}
$('#grabbit').click(function() {
//call checkBalance function on click
checkBalance(function(myTokensLeft){
// do something with myTokensLeft
});
});
EDIT: more details
the function balanceRef.on does not return your desired data, it only attaches the function function(snapshot)... to the object balanceRef's value event.
When the object balanceRef's value event gets triggered (i.e. data is available), your function function(snapshot)... gets executed, but it's return values goes nowhere, because the javascript parser has already moved on.
try this:
function checkBalance(){
balanceRef.on('value', function(snapshot){
return 'foo';
});
return 'bar';
}
$('#grabbit').click(function(){
console.log(checkBalance());
// this will print 'bar' in your
// in your console, not 'foo'
});
EDIT 2: to avoid callback chaining, one can use a variable that will be common to both functions. (not a very good practice though, since you cannot be sure that the value has been set, when you want it!)
(function(){
// added the closure to avoid myTokensLeft cluttering
// into global variables
var myTokensLeft;
balanceRef.on('value', function(snapshot){
var mLeft;
if (snapshot.val()=== null){
mLeft=0
} else{
mLeft=snapshot.val().tokensLeft
}
myTokensLeft = mLeft;
});
$('#grabbit').click(function(){
// do something with myTokensLeft
});
}());
It seems to me that on your click event you only create another listener to "value" event and gods know how and when that event is triggered and where the function returns your mLeft.
What is happening in your code is that after each click on "#grabit" always new listener is created, but the function inside is not necessarily to be called and if it is called it is called asynchronously which means by the time it is finished you already got "undefined".

JavaScript Too much recursion error with facebook JavaScript SDK

i am sending FB.login request to facebook. but FB is not defined while javascript SDK is still loading core javascript resources.
so, i put a check to get FB variable
function check_FB_variable(){
if(typeof FB=='undefined'){
check_FB_variable();
}else{}
}
check_FB_variable();
But this approach gives me Too much recursion error.
so , i put this code as
function check_FB_variable(){
if(typeof FB=='undefined'){
setTimeout(check_FB_variable,600);
}else{}
}
check_FB_variable();
but in this approach the before timeout function make a call function moves down and gives error
FB.login not defined.
please, help.
I've used something similar to check if JQMobi exists, I don't know exactly why but I think the exception is thrown because you call the pointer to the function every time.
You should try checking in an interval like this (Untested):
var facebookChecker = window.setInterval(fbCheck, 200);
var fbCheck = function () {
if (typeof FB != 'undefined' && facebookChecker != null) {
window.clearInterval(facebookChecker);
facebookChecker = null;
// Whatever you want to do if facebook is loaded
// Example: InitFBLogin();
}
}
Or you could use a while statement (the one I used):
/*
* This JQ Fix tries to attach Jquery to a variable to ensure it exists.
* - Marvin Brouwer.
*/
var FixJQ = function () {
var JQFIX = null;
while (!JQFIX || JQFIX == null) {
try {
JQFIX = jQuery;
} catch (nothing) { jQuery = $; };
};
JQFIX = null;
return true;
};
if (FixJQ()) {
FixJQ = null;
};
The beauty of the last one is that you can put you next step below this, because it will wait until the while loop has finished.
I honestly do not know which one is better/faster but I’m sure the bottom one will work.

Open social viewer state (isOwner)

We are creating a gadget for the opensocial API 0.7.
In some functions we have to decide, if the viewer is the owner.
We couldn't use the usual function for this purpose:
return gadgets.util.getUrlParameters().viewer == gadgets.util.getUrlParameters().owner;
so we had to create a workaround and get the information via a DataRequest.
The DataRequest calls a callback function and has no useable return value.
We tried a quick hack by using global variables to set the corresponding value.
The issue at this point is, that the function does not 'wait' for the callback-function to be finished. We know this is no good code/style at all, but we tried to force a timeout for debug reasons.
Handling all the code within the callback-function (as suggested in the examples of the opensocial docs) is not possible.
We are looking for something like a real 'sleep()' in JavaScript to wait for the callback-function to complete or another alternative to get the owner information about the viewer.
globalWorkaroundIsOwner = false;
function show_teaser(){
if (current_user_is_owner()){
// ...
}
// ...
}
function current_user_is_owner() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
// This will set the the correct value
req.send( user_is_owner_workaround );
// This is an attempt to delay the return of the value.
// An alert() at this point delays the return as wanted.
window.setTimeout("empty()", 2000);
// This return seems to be called too early (the variable is false)
return globalWorkaroundIsOwner;
}
function user_is_owner_workaround(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
globalWorkaroundIsOwner = viewer.isOwner();
// value is correct at this point
}
Can you use an additional flag in order to indicate whether the remote query has already returned the required value?
var globalWorkaroundIsOwner = false;
var workaroundStarted = false, workAroundComplete = false;
var checker;
function show_teaser(){
if (!workaroundStarted) {
workaroundStarted = true;
current_user_is_owner();
}
if (workaroundComplete) {
if (globalWorkaroundIsOwner){
// ...
}
// ...
if (checker) {
clearInterval(checker);
}
}
}
function current_user_is_owner() {
var req = opensocial.newDataRequest();
req.add(req.newFetchPersonRequest(opensocial.DataRequest.PersonId.VIEWER), 'viewer');
checker = setInterval("show_teaser()", 1000);
// This will set the the correct value
req.send( user_is_owner_workaround );
}
function user_is_owner_workaround(dataResponse) {
var viewer = dataResponse.get('viewer').getData();
globalWorkaroundIsOwner = viewer.isOwner();
workAroundComplete = true;
// value is correct at this point
}

Categories

Resources