Execution order with javascript and race conditions? - javascript

I was under the impression that javascript executed all lines at the same time and this is one thing that makes it different from many other programming languages. I have the following code for a simple index;
var newAcceptIndex = 0;
function addNewAccept(event) {
var newAccept = `some new accept ${newAcceptIndex}`
$(event.target).closest("[id^='new_item_']").before(newAccept);
newAcceptIndex += 1
};
I would have expected newAcceptIndex on the first call to be 1 since all code should be executed at the same time and thus set to 1 instead of 0. Am I encountering a race condition or is this working as intended?

JS code does not run all at the same time, you're probably just thinking about the hoisting JS does with their variables and functions so they don't immediately throw errors. You just need to reorganize your code like how it would be in other programming languages - executed from top to bottom:
var newAcceptIndex = 0;
function addNewAccept(event) {
newAcceptIndex += 1
var newAccept = `some new accept ${newAcceptIndex}`
$(event.target).closest("[id^='new_item_']").before(newAccept);
};

Related

Create a re-usable type writer effect function in Javascript?

I know the basics of what I need to do here, but my attempt at coding it is riddled with problems so here is what I want to do.
Define a series of strings to be called up into a function that types it onto the screen with a slight delay between each letter.
I've found some examples of people making typewriter title cards, but these are not designed to be used like functions that can be called up on the fly. For this particular project, we need the text to function like a makeshift dialog system that won't be called up until the function is called with a specific string.
Like a button with " onclick="dialogFunction(idOfStringToBeTyped) "
what I have looks like this:
var d1Example = "Hello, I am example dialog";
function dialog(dialogString) {
var i;
for (i = 0; i <= dialogString.length(); i++) {
document.write( dialogString.charAt(i) );
java.lang.Thread.sleep(50);
}}
So my attempts to code the content has been... brute force-y...
EDIT: to include my attempt, should have been there in the first place, sorry about that.
This, in theory, should work, but in practice does nothing. I probably have a syntax error. but really it doesn't make sense to me why this doesn't work.
You should look into the JavaScript functions setTimeout and Math.random().
You can use Math.random() to create a floating point integer between 0 and 1.
var multipule = 5
var rand = Math.random(); // 0.5680401974599227
var randInSeconds = rand * multipule // 2.840200987299614
var waitInSeconds = Math.round(randInSeconds) // 3
Then use the the setTimeout out method to call the code that writes each character. setTimeout takes two parameters, a function and the number of seconds:
var writeCharacter = function(){
...
};
setTimeout(writeCharacter, 300);
I'll leave it to you to work out all the timing.

Beginner query: Using function parameters with a for loop, skipping the loop for some reason

I imagine this is something pretty simple but I'm stumped and think this could be a good learning moment for me.
Here's the code:
var sumAll = function(lowRange, highRange) {
var sumOf;
var i;
for (i = lowRange; i > highRange; i++) {
sumOf += i;
}
return sumOf;
}
module.exports = sumAll
I'm working my way through the odin project, currently doing TDD section. So the function skeleton and final line of code was premade. The function parameters in this case are 1, 4. Expected result of 10.
Instead my test is throwing back undefined. I checked and this changes depending on what I define it as at the top.
It is as if it's skipping the loop all together, I've no idea why this would be.
A for loop's 3 major pieces can typically be understood like this.
Initialize the variable
Continue looping for as long as the condition is true
Change the variable's value after every iteration
During step two of the list above, your code is running i > highrange. This will immediately test false and skip your loop, because i has a value of lowrange, and I assume lowrange > highrange will never be true. What you want in its place is i <= highrange, "less than or equal to."
For loops are tricky, these little mistakes will follow you even into advanced territories. :o
Your for loop never executes because you set i equal to lowRange and the execute condition is i > highRange. I assume lowRange < highRange so it terminates without entering the loop, since it will run while i is greater than highRange, but it never is.
initialize your accumulator
var sumOf = 0;
and change your loop condition
for (i = lowRange; i <= highRange; i++) {

Javascript: TypeError variable is undefined

I am currently building a small web application with similar functionality across all modules. I want to code small generic functions so that all programmers next to me, call these functions and these functions return necessary but important data for them to implement their functionality. In this example, I am trying to deal with the typical "choose true or false" exercise. So from the template.php they call this function:
function checkAnswers(){
var radiobuttons = document.form1.exer1;
var correctAnswers = answers(); //this is an array of string
var checkedAnswers = checkExerciseRB(radiobuttons, 2, correctAnswers);
for(i=0; i<checkedAnswers.length; i++){
alert(checkedAnswers[i]);
}
}
Function checkExerciseRB is my generic function, it is called from checkAnswers.
function checkExerciseRB(rbuttons, opciones, correct){
var answers = new Array();
var control = 0;
for(i=0; i<rbuttons.length; i++){
var noPick="true";
for(j=0; j<opciones; j++){
if(rbuttons[control+j].checked){
if(rbuttons[control+j].value==correct[i]){
answers[i]= 1;
noPick="false";
break;
}
else{
answers[i]=2;
noPick="false";
break;
}
}
}
if(noPick=="true")
answers[i]=0;
control=control+opciones;
}
return answers;
}
It works great but while looking at my favorite browsers (FireFox, Chrome) error log it says:
TypeError: rbuttons[control + j] is undefined
Any clue on how to deal with this matter?
This probably means that control + j is greater than or equal to the length of the array rbuttons. There's no such array element as rbuttons[control + j].
You should learn how to use the JavaScript debugger in your favorite browsers! Debuggers are great. They let you watch this code run, line by line, as fast or as slow as you want, and watch how the value of control changes as you go.
You’ll watch it, and you’ll think “Oh! That line of code is wrong!”
You're looping through rbuttons.length times, but in each loop you're adding 2 to control. Using control to index your array, you're going to run past the end.
Does the index specified by control + j exist in the array? i.e: If that evaluates to 4, is there at least 5 items in the array?
Also, you should be using var i, var j, etc inside your for loop. Without it your variables are leaking into the scope this code is executed in (most likely the global scope, and that's not good) :)

global variables javascript, which is faster "varname" or "window.varname"

var testvar = 'boat';
function testA() {
console.log(testvar);
}
function testB() {
console.log(window.testvar);
}
I know that if I don't put the "window." for my global variable, then javascript searches all the scopes from method testA onward until it finds the variable testvar, so if I do window.testvar instead does it make it faster because I'm directly telling javascript which scope to look in for the variable? Or slower because I'm first telling javascript to look for the window object and then the variable?
Try both of the codes below separately and see the results for yourself. Indeed this might not be the most accurate testcase however by avoiding all other manipulation and doing a simple assignment inside a long enough for loop it ought to be accurate enough.
I have to say I was also surprised to see that by not specifying window Chrome persistently reported about 20% faster execution for the second code.
CODE 1
// window.testvar testcase.
window.testvar = 'Hi there! I am a testvar!';
var tmp;
var start = new Date();
for(var i = 0; i < 1000000; i++){
tmp = window.testvar;
}
var stop = new Date();
console.log('This took exactlly ' + (stop.getTime() - start.getTime()) + ' milliseconds!');
RESULTS:
1695ms
1715ms
1737ms
1704ms
1695ms
CODE 2
// direct testvar testcase
testvar = 'Hi there! I am a testvar!';
var tmp;
var start = new Date();
for(var i = 0; i < 1000000; i++){
tmp = testvar;
}
var stop = new Date();
console.log('This took exactlly ' + (stop.getTime() - start.getTime()) + ' milliseconds!');
RESULTS:
1415ms
1450ms
1422ms
1428ms
1450ms
Tested in Chrome 20.0.1132.47.
Vedaant's jsperf was not helpful. It was only creating functions, not executing them. Try this one: http://jsperf.com/epictest/9. It too shows that not specifying window is faster. I also added a test to show that copying to a local variable is dramatically faster. Vary the loop counter to see that you win for anything more than a single reference to the global.
Chrome has a useful javascript CPU profiler. Just create a loop to run the function several thousand times and start the profiler. I'm guessing that the difference is very small but this would be a good way to know for sure.
I just made a jsPerf test for you, check it out at: http://jsperf.com/epictest. It seems that
function testA() {
console.log(testvar);
}
is a bit faster.

how to make sure some piece of code is executed before all other codes in java script?

I am a newbie in javascript and what makes me so confused in the order of operations in Javascript.
lets suppose I have a following code:
var myArray = [];
function getArray(x){
var _array = [];
.... {the code here is pretty big}
return _array;
}
myArray = getArray(1);
and rest of the code are all based on myArray. Unfortunately, using this code sometimes myArray is not set in time so the rest of code doesn't work properly. Is there anyway that I can make sure the rest of the code is executed when myArray is set properly?
Thanks,
Amir.
Place it at the top of the js file or html before any other javascript and it will execute first. This assumes you don't have it wrapped in some sort of delay like setTimeout or jQuery's document ready function.
JS executes as it is loaded by the web browser, so the order it appears in determines the order it executes in relative to other JS.
> var myArray = [];
There are two phases to javascript processing: the first processes all declarations, the second executes the code. So regardless of where myArray is declared, it will be declared before any code is executed.
When code execution begins, statements are executed in sequence so myArray is assigned an empty array before the following code is executed.
> function getArray(x) {
> var _array = []; ....
> // the code here is pretty big
> return _array;
> }
Similarly, getArray will also be defined before any code is run.
> myArray = getArray(1);
This replaces the array assigned to myArray above with whatever is returned by getArray.
If, from time to time, the value of myArray is not what you expect, then it is a consequence of whatever is being returned by getArray, so I would concentrate on that.

Categories

Resources