Button Click and Timeout calling the same function in javascript - javascript

I am working on an ionic project, and as part of this project, the user will have to complete a timed task. They have to answer a multiple choice question in 15~ seconds, otherwise they fail the task.
I currently have a timeout in the background, which will call function "evaluate" in the background, and disable the multiple choice answer buttons. This function is also called by the click of one of the multiple choice answer buttons.
Is there a danger of an edge case where the user selects the button just as the timeout calls the evaluate function, leading to the function being called twice? How can I avoid this?

As far as I known, there is no way to have a "race condition" in a web browser session, basically because each tab in a web browser runs in a single thread, so your logic will runs in a single runloop. You can use this fact to implement a flag indicating what happens first, but (honestly) this is pretty ugly.
I think the most elegant solution should be to make the function evaluate idempotent, that way, you don't care if is called several times.

You could have a variable named something like "eval_running" that you check in your evaluate function. If it is false, you set it to true and proceed evaluating. If it is true, you return from the function without evaluation. When you display the next task, you reset the variable to false.
That would prevent any kind of race condition. The time frame in which a double execution could occur depends on how long the eval function is working in the background. Chances are, you do not need to worry about this.

The best approach in this scenario is not very complicated. So the timeout trigger and also the submit button are calling the same evaluatefunction.
All you need to do is this. Disable the submit button immediately at the opening of the function and then write whatever you want to do. So if the timeout calls the function first, the button will be disabled before executing the operations, and the user cannot click the button anymore. If the button is clicked first, then it goes as it should and there's no complication here.

Related

Custom alert/confirmation box

Is it possible to make a custom alert/confirm/prompt that have the same behaviour as native javascript windows (without using callbacks/asynchronous events)?
Ex.:
if(mytest == true){
myCustomMsgWindow('message'); //Pause execution
//do something
}
I tried this once but dint works for confirm window because it must return a value.
You can make custom ones but their behavior will not be the same.
Because in the browsers these boxes pause the execution thread, and resumed by user action. you can not pause the execution thread, this is implicit.
However there are some workaround which may behave almost similar. You can try that
BootBox
No, you cannot write JS code that blocks (pauses execution) waiting for user input on without alert or confirm. You have to listen for events within your dialog asynchronously (through events)
The solution is use callbacks as you have already mentioned, not sure why you don't want to use that.

What is the opposite of javascript window.stop()

Once I've executed window.stop(), how can I resume default actions?
I need to make toggle/switch function, that once fired will run window.stop(), and with second run will recover window actions disabled by window.stop().
I misunderstood before how window.stop() works.
I was wrong, there are no any "direct inbuilt" javascript method to reload ONLY THESE ELEMENTS stopped by window.stop(), so by this meaning it's impossible.
However, if it's needed, we can:
loop through each element on the site by our own function
cut website in sections, and load them one by one with ajax, so we will have to reload only specific sections
--but I think either one of these it's too complex to implement to be worthy
So, to "pause website for moment" window.stop() it's not good choice.

What's the easiest / most efficient way to pause setInterval while data is loading? JavaScript/Jquery

So i have a JS Interval doing a load command on a script.. and displays the loaded data on a div..
Everything was perfect until i put my project online and saw an issue (in the background)..
Since the setInterval needs to be set at 1 second interval , and a lot of times the time it takes for the data to load is more than 1 second, i see load stacking happening in the background... since the setInterval continues to fire $.load() calls every second regardless of any loaded data..
I was thinking of setting a global variable "is_loading" to add to my function in the interval, to skip the rest of the routine incase "is_loading" is true, .. once the recent load call completes, it sets is_loading = false..
this way the interval keeps firing / second w/o load calls stacking in the background...
however, since i have several intervals doing loads all over the page (pls dont ask why lolz) i find it quite tedious to do this w/ every interval.. therefore i was wondering is there something i can do "globally" like an event listener of some sort for current unfinished loading/get/post happening on the page?
Suggestions would be great
Like others have said, I would use setTimeout to make a new request whenever a request completes.
For dealing with multiple requests on a timer, I recommend making some sort of master timer/scheduler in order to decrease the amount of setTimeouts running all over. This article from Google is was helpful to me when I was doing something similar:
http://googlecode.blogspot.com/2009/07/gmail-for-mobile-html5-series-using.html
There were some great suggestions (and reminders) here, but what I'm going to do is create my own setInterval function that does what i want to do..
myInterval(function,time,hold_variable,attempts)
where
hold_variable = window.variable issued and checked for before executing the actual function. this is the same variable name my function will set back to 0 when it finishes and allows another call of itself
attempts = optional variable, the count of how many times the interval attempts to call the function unsuccessfully due to the hold_variable..
this is a pretty straight forward solution on the setInterval side.. only inconvenience is that my functions need to "set" each of their hold_variables (a tiny modification on each function)...

Hold execution of script

just wanted to know if it is programatically possible to halt the execution of script the same way javascript function "confirm" does. "confirm" stops further execution of script until user input, i want to acheieve same thing for BlockUI plugin of Jquery.
No, you cannot.
confirm, like the alert function, is a modal dialog, which is nothing more than a child window that requires users to interact with it before they can return to operating the parent application, thus preventing the workflow on the application main window.
Javascript has no sleep-ing mechanism. If you want to stop the execution of a script... it's only possible by executing another script that is memory/CPU expensive (such as an infinite loop) that will freeze the browser (thus stopping the targeted script from executing), but that kind of defeats the purpose.
If you know what you want to do, you can organize your code in such a manner that you can simulate the sleep process.
A good way of doing that is using callbacks combined with timeouts:
function f1(callback){
// do some stuff
// decide how much you want to wait
setTimeout(callback,how_much_you_want_to_wait);
}
I don't think its possible... the best you can do is,
show an overlay div which prevents any other user interactions on page
show your html popup in front of the overlay
in the code, use callbacks or 'jquery binders' or 'event listers' to execute the rest of the code
A rough example could be,
function showDialog(fn){
$('#overlay').show()
$('#dialog').show().click(fn); // ideally bind the click to the close button of the dialog
}
now, to show the dialog,
// code before the dial
showDialog(function(){
// execute rest of the code
})
Javascript has no sleep function that may be available in other languages. The best you can do is a setTimeout.
You could possibly do while true style loop but that will just spike CPU usage which is usually not encouraged.

What is triggering the "Tags" section of Stackoverflow?

Been looking for hours. At https://stackoverflow.com/questions/ask how does the "Tags" section make the blue boxes appear below?
I don't think they are using keyup event trigger, since the blue boxes are not being updated on every keypress.
You can test this by going to https://stackoverflow.com/questions/ask and typing:
"aadfadasdfasdfasdfasdfasfasdfsaf"
As you type, you will notice that the blue box "aadfadasdfasdfasdfasdfasfasdfsaf" will only appear a few seconds AFTER typing. Not during.
They probably call setTimeout and clearTimeout to run their code 1 second after the last keyup event.
It's just a case of autocomplete. There are many ways of accomplishing this.
One way is to store the list of words to autocomplete on the client end. This is very fast and there won't be any delay (unless you program one in).
The other way is to make an AJAX call to the server and have it return a list of autocomplete words. This is how SO does it. Since you don't want to make an ajax call every time the user types in a letter, there is a delay implemented to save bandwidth and improve performance.
If you want to implement a similar feature on your own website, I suggest looking into jQuery plugins to achieve this as there are many freely available ones out there.
EDIT: The trigger is likely a keyup event as you mentioned. However the trigger will likely wait for a second or so using setTimeout() before showing the list of possible autocompletes. clearTimeout() is used if another key has been pressed during the delay to prevent multiple calls from being made.
Check out the source code using Firebug or another web inspector. You'll see that there's a file called full.js. It's minimized, but you can expand the code using a variety of online tools; I go the very lazy approach of copying/pasting the whole thing into the "javascript" box in jsfiddle and hitting "tidy". I'm sure there are better (and faster) ways to do it.
Anyway, in that file, there are a few functions that may interest you: StackExchange.tagPreferences and it's subfunctions, initTagRenderer, and StackExchange.inlineEditing. I think the last function is the one that causes the specific delay you're referring to, but it's pretty hard to tell.

Categories