Why doesn't Javascript execute the code in sequence? - javascript

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

Related

cache existing function and add to it and run additions when another function called

I have the following existing function that I'm unable to access and change. So I've had to cache it and add other functions to it.
The function loads periodically and sometimes load on page load and sometimes doesn't. The additional functions I've added to it , I don't ever want loading on page load however.
I have tried the following with no luck. I can not prevent update_scores from loading on page load , so the if(onSwitch) is true , then and only then I want to add something else to the existing function. Once onSwith is true , then I need all additional functions to always execute when update_scores runs, but initially only after another function click() is called.
function click() {
update_scores(true);
}
update_scores = (function(onSwitch) {
var cached_function = update_scores;
return function() {
let update_scores=true; // always do something below when update_scores after function click ran once
cached_function.apply(this, arguments);
if(onSwitch) {
//Do something only when function click is ran or until onSwith is defined as true
}
};
}());
ok , i was able to achieve by setting a global variable , then changing it when i ran another function
var onSwitch = false;
function click() {
update_scores(true);
onSwitch = true;
}
update_scores = (function(onSwitch) {
var cached_function = update_scores;
return function() {
cached_function.apply(this, arguments);
if(onSwitch) {
//Do something only when function click is ran or until onSwith is defined as true
}
};
}());

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.

Javascript running code once

I only want my JavaScript to run once, but I cannot control how many times the javascript file is executed. Basically I'm writing a tiny JS snippet into a CMS, and the CMS is actually calling it 5-10 times. So solutions like this:
function never_called_again(args) {
// do some stuff
never_called_again = function (new_args) {
// do nothing
}
}
never_called_again();
Don't seem to work because as soon as my snippet is run again from the top the function is re-declared, and 'do some stuff' is re-evaluated. Perhaps I'm just not doing it properly, I'm not great with JS. I'm considering using something like try-catch on a global variable, something like
if (code_happened == undefined) {
\\ run code
code_happened = true;
}
EDIT: There is a consistent state e.g. if I set a variable I can see when my snippet is run again. But having to declare it before I access it, I don't know how to say 'does this variable exist yet'
Try this:
var doneTheStuff;
function whatever() {
if (!doneTheStuff) {
doneTheStuff = true;
// do the stuff
}
}
Redundant variable declarations don't affect the value of the variable. Once one of the functions has set the variable to true, the others won't do anything.
if (typeof code_happened === 'undefined') {
window.code_happened = true;
// Your code here.
}
The typeof check gets you around the fact that the global hasn't been declared. You could also just do if (!window.code_happened) since property access isn't banned for undefined properties.
Use a closure, and set a flag. If the flag is true, just return:
if ( ! window.never_called_again ) {
window.never_called_again = (function () {
var ran = false;
return function (args) {
if ( ran ) return;
ran = true;
// Do stuff
};
}());
}
Here's the fiddle: http://jsfiddle.net/U2NCs/
With jQuery, the function .one() may be useful : http://api.jquery.com/one/
W3School exemple here : http://www.w3schools.com/jquery/event_one.asp
In this way, the code is executed only once.
if(typeof onceRun == "undefined") window.onceRun=(
()=>{
//your codes...
console.log("runing...")
return true
}).call()

Titanium mvc - call function and wait for result

I am currently in the process of making my first Titanium iPhone app.
In a model I got:
(function() {
main.model = {};
main.model.getAlbums = function(_args) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
// Runs the function when the data is ready for us to process
loader.onload = function() {
// Evaluate the JSON
var albums = eval('('+this.responseText+')');
//alert(albums.length);
return albums;
};
// Send the HTTP request
loader.send();
};
})();
and I call this function in a view like:
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var albums = main.model.getAlbums();
alert(albums);
return albumsWindow;
};
})();
however it seems like the call to the model (which fetches some data using HTTP) doesn't wait for a response. In the view when I do the alert it haven't received the data from the model yet. How do I do this in a best-practice way?
Thanks in advance
OK,
Something like this,
function foo(arg1, callback){
arg1 += 10;
....
... Your web service code
....
callback(arg1); // you can have your response instead of arg1
}
you will call this function like this,
foo (arg1, function(returnedParameter){
alert(returnedParameter); // here you will get your response which was returned in above function using this line .... callback(arg1);
});
so here arg1 is parameter (simple parameter like integer, string etc ... ) and second argument is your call back function.
Cheers.
What you need is Synchronous call to web service, so that it will wait till you get the response from the service.
To achieve this in java script you have to pass callback function as parameter and get the return value in callback function instead of returning value by return statement.
Actually coding style you are using is new for me because i am using different coding style.
But the main thing is you have to use call back function to retrieve value instead of return statement. Try this and if you still face the problem than tell me i will try to give an example.
the callback way like zero explained is nicely explained, but you could also try to get it handled with events.
(function() {
main.ui.createAlbumsWindow = function(_args) {
var albumsWindow = Titanium.UI.createWindow({
title:'Albums',
backgroundColor:'#000'
});
var status = new object(), // eventlistener
got_a_valid_result = false;
// catch result
status.addEventListener('gotResult',function(e){
alert(e.result);
got_a_valid_result = true;
});
// catch error
status.addEventListener('error',function(e){
alert("error occured: "+e.errorcode);
git_a_valid_result = true;
});
var albums = main.model.getAlbums(status);
// wait for result
while (!got_a_valid_result){};
return albumsWindow;
};
})();
and your model may something like
main.model.getAlbums = function(status) {
var loader = Titanium.Network.createHTTPClient();
loader.open("GET", "http://someurl.json");
loader.onload = function() {
var albums = eval('('+this.responseText+')');
status.fireEvent('gotResult',{result:albums});
return albums;
};
loader.onerror = function(e){
status.fireEvent('error',{errorcode:"an error occured"});
};
// Send the HTTP request
loader.send();
};
Just as a suggestion, try to use JSON.parse instead of eval as there are risks involved with using eval since it runs all javascript code.
I think that the solution The Zero posted is likely better for memory management, but I'm not totally sure. If you do and eventListener, be aware of the following
(see https://wiki.appcelerator.org/display/guides/Managing+Memory+and+Finding+Leaks)
function doSomething(_event) {
var foo = bar;
}
// adding this event listener causes a memory leak
// as references remain valid as long as the app is running
Ti.App.addEventListener('bad:idea', doSomething);
// you can plug this leak by removing the event listener, for example when the window is closed
thisWindow.addEventListener('close', function() {
// to remove an event listener, you must use the exact same function signature
// as when the listener was added
Ti.App.removeEventListener('bad:idea', doSomething);
});

How to lock AJAX functions from overlapping?

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...

Categories

Resources