There is synchronization issue between localstorage and server.
Countries,Cities,Users are synchronized with server seperately.(Seperate ajax calls)
The problem is other Javascript codes (Kncokout Bindings and etc.) must wait synchronization process. Or better a javascript function have to wait another one.
How can I implement it?
PS: I'm using jquery,amplifyjs (for localstorage interaction),knockoutjs libraries.
PS2: I need cross browser solution :)
EDİT
Summary:
I have 3 Javascript functions. All of them makes asynchronous ajax call with callback.
These functions could work as parallel.(Don't have to wait each others)
But the code have to work after these 3 functions.(Because these functions are synchronizing local storage and the code uses localstorage)
Use deferred objects and $.when, that's one of it's primary uses.
$.when($.ajax(...),$.ajax(...),$.ajax(...)).done(function(){
// all three are done
});
Here is one way you can implement this, provided that you are initiating the ajax calls at the same time. A simple count-track can solve it -
var countCalls;
Then in your ajax related code:
function initAjaxCalls() {
countCalls = 0; //(re)set counter
startAjax1(commonCallback); //pseudo call, use commomCallback as callback
startAjax2(commonCallback);
startAjax3(commonCallback);
}
On the callback we keep track of number of calls:
function commonCallback(e) {
countCalls++;
/// when we have reached the max count, perform the sync. step
if (countCalls === 3) performSyncStorage();
}
This will wait until the longest lasting operation has finished. This is necessary if you want to sort of convert an asynchronous operation into a synchronous one.
Related
i have a little problem in understand of callbacks. I have read a lot in the last 2 days and what i have understand is the following (correct me, if i'm wrong):
JavaScript is a single thread language and you can program synchronous and asynchronous.
Synchronous means, each statement waits for the previous statement to finish before executing. That can lead into trouble, because if for instance a connection to a database needs a lot of time, the statements after the previous has to wait.
Finally that's very bad and that's why it's better to program asynchronous in Javascript, because Asynchronous code doesn't have to wait, the code can continue to run and the user don't have to wait.
To program asynchronous the Callbacks (functions of higher order) are needed.
Now i have try to program a little example by a lot of tutorials, etc.
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
callback(10);
}
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
Is that right? the output is:
1.function and given parameter: 5
2.function and given parameter of 1. function: 10
I do not understand, what the advantage is of this code, because i think that can still lead into trouble? If "console.log('1.function and....') has problems, the callback(10) function would even stop or not?
Thanks for any help!
JavaScript is a single thread language...
No, it isn't. The language says nothing about threading. Most environments give you a single thread per global environment, though (and on browsers you can create more, which interoperate through messaging). NodeJS provides just the one thread. Some environments (such as Rhino or Nashorn on the JDK) provide true multi-threading (and all the advantages and hassles that can involve).
Using a callback doesn't make code asynchronous. Your example, for instance, is not asynchronous. Consider:
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
callback(10);
}
console.log("Before the call");
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Note how we don't see After the call until after 2.function and given parameter of 1. function: 10. If the callback were asynchronous, we'd see it before:
function testCallback(a,callback){
console.log('1.function and given parameter: '+a);
setTimeout(function() { // Using setTimeout
callback(10); // to make this call
}, 0); // asynchronous
}
console.log("Before the call");
testCallback(5 , function(x){
console.log("2.function and given parameter of 1. function: "+x);
});
console.log("After the call");
Whether a callback is called synchronously or asynchronously depends entirely on what the function you're passing it to does. For instance, the callback used by Array#sort is called synchronously, but the callback used by setTimeout is called asynchronously.
For code to be asynchronous, it has to start an operation and then have that operation complete later, triggering a callback. setTimeout does that, as does ajax when used correctly, as do a wide range of other things.
Note that callbacks are currently how you handle asynchronous behavior (simple callbacks like the above, or promise callbacks), but the next specification (ES2017) will define built-in language semantics for dealing with asynchronousity without callbacks in the form of async and await. You can use that syntax today if you transpile with a tool like Babel.
In javascript callbacks can be synchronous or asynchronous. Synchronous callbacks can have a lot of benefits, but they don't do anything to stop your code blocking.
I think the best way to understand what asynchronous code is, and why it's beneficial, is to learn how Javascript actually evaluates your code. I recommend this video, which explains the process very clearly https://www.youtube.com/watch?v=8aGhZQkoFbQ
A JavaScript Callback Function is a function that is passed as a parameter to another JavaScript function. Callbacks can be synchronous or asynchronous. Simply passing a function as parameter will not change its current behavior.
It's behavior can be changed by the method which will execute it by calling it inside an event listener or setTimeout function etc. Basically event listener or setTimeout etc are handled by webapi in async fashion. If callback functions are inside these functions then these are moved to a queue by webapi when they are activated like button click(event listener) or time declared in setTimeout passed. They will move from queue to stack(if stack is empty) and run on stack finally.
The main advantage of using callback function can be seen from below code :-
var add = function(x,y) {
return x+y;
}
var multiply = function(x,y){
return x*y;
}
var calculate = function(x,y,callback){
return callback(x,y);
}
console.log(calculate(4,9,add));
I have a function that has integration with my database, but before that I have a function which does some checks:
function checkVars (a, b){
if (a.a1 !== b.b1){
b.b1 = a.a1;
}
// and other 4 vars
}
After this I have a function to insert data into my database.
How can I be sure that my code is going to execute the comparative function before the database function?
I am using a callback, but is that possible without callbacks?
How can i be sure that my code is going to execute the comparative function before ?
Assuming you have:
checkVars(something, somethingElse);
doDatabaseWork();
...you know checkVars will be called and will run to completion before doDatabaseWork is called. Since checkVars does all of its work synchronously (it doesn't start any asynchronous processes), the fact it runs to completion before doDatabaseWork is called means all of its work is done before doDatabaseWork. It's only if checkVars starts an asynchronous process that you need to allow for that process not being complete yet when checkVars returns (and handle it via callbacks, direct ones or via promises). But what you've described doesn't start an asynchronous process in checkVars, so there's nothing to allow for.
I have a settings page on my jQuery mobile website When user clicks save button, I update the server for 3 different user inputs i.e language, currency, threshold
In order to do this I make 3 separate ajax calls (with PUT). So when all are succesfull I go to another page if any of those fails I stay on the same page and show the error messages.
The problem is I only want to switch the page if all calls are succesful, and if there are any errors I want to show one alert with all messages (rather than 3 separete alert windows), so I need to wait the results of all these calls.
To achive this in all 3 Ajax calls I used;
async:false
And I put a boolean in all these calls succes methods like;
success: function (data){
languageUpatesuccesful=true;
}
and then something like this;
if(languageUpatesuccesful){
make the next call to update currency..etc
}
...
if(allsuccesful(){
changepage();
}
So I can track when exactly when one calls finishes then I make the next call, if all succesful switch to another page.
While this works, I think this is a horrible solution, is there a way to achive this by using async:true ?
Because disabling asynchrous ajac freezes the page and I cant even show animations, also it is not recommended by jQuery. But then how can I know when these 3 calls are finished and take action depending on result?
Use deferred objects together with $.when:
$.when(ajax1(), ajax2(), ajax3()).done(function() {
// all Ajax calls successful, yay!
}).fail(function() {
// oh noes, at least one call failed!
});
Where ajaxX is defined as:
function ajax1() {
return $.ajax(...);
}
If you indeed want to chain the Ajax calls instead of having them concurrent, have a look at Bergi's solution.
You can easily chain them by using the Deferred interface:
$.ajax({…})
.then(function(languageUpateResult) {
return $.ajax({…});
})
.then(function(currencyUpdateResult) {
return $.ajax({…});
})
.then(function(thresholdUpdateResult) {
changePage();
});
Sorry, I skipped the fact that the ajax calls are separate. The above code executes them sequentially, if you just want to execute them in parallel and wait for all of them to finish use $.when() - see #FelixKling's answer.
You can try using web workers to do your async calls in a background thread. Web workers have pretty good browser support and should solve your issue. If you are interested, I have written a little abstraction of the web worker library to make them easier to work with (just send me a pm).
Promises in JS allow you to do async programming, as follows:
DoSomething().then(success, failure);
DoSomethingElse();
whenever i write the previous code it reaches DoSomethingElse() before it reaches success.
How is that possible? Isn't JS a single threaded environment (not including web-workers)? is it done with setTimeout?
Yes, JavaScript is single-threaded, which means you should never block this single thread. Any long-running, waiting operation (typically AJAX calls or sleeps/pauses) are implemented using callbacks.
Without looking at the implementation here is what happens:
DoSomething is called and it receives success and failure functions as arguments.
It does what it needs to do (probably initiating long-running AJAX call) and returns
DoSomethingElse() is called
...
Some time later AJAX response arrives. It calls previously defined success and failure function
See also (similar problems)
JavaScript equivalent of SwingUtilities.invokeLater()
Are there any atomic javascript operations to deal with Ajax's asynchronous nature?
jqGrid custom edit rule function using Ajax displays "Custom Function should return array!"
Promises in JavaScript usually involve some kind of call chains or fluent method call APIs, where function results usually provide continuation methods like with, then, when, whenAll etc plus some status flags that indicate if the result is in fact available. Functions with input parameters can also support promised values detecting that the input is a promise and encapsulation their functionality into a thunk that can be chained when the promised value is ready.
With these you can provide an environment where promises simulate a parallel language like this:
MyApi.LongRunningTask().then( function(result) { MyAppi.LongOtherTask(result); }).then
or a sequential use case where long running calls are not dependant:
var value1 = MyApi.LongRunningTask();
var value2 = MyApi.LongRunningOtherTask();
MyApi.DoSomeFunction( value1, value2).then ==> DoSomeFunction can check if values are ready and if not chains their then/when function to execute its logic.
I understand that Javascript doesn't have multiple threads, but I'd like to know if the following code has any chance of breaking. My understanding is that unless an asynchronous function is called, such as setTimeout or an AJAX call, that once a block of code starts executing there's no way for it to pause until it completes or does call an asynchronous function.
Basically, users select multiple checkboxes and then hits a button that executes AJAX processing of their selections. My goal is to have a "Saving..." icon that stays only until all the AJAX processes are complete, and after all are finished display a success message.
Barring any AJAX errors, so long as the callback function in the jQuery.post executes in its entirety without interruption, I don't see how the if(numProcessed == toProcess) would ever execute more than once or less than once. But if two AJAX callbacks get into the callback function, both increment the numProcessed counter before either get to the following if, then it seems that the code inside would be executed twice.
var numProcessed = 0;
var checkedBoxes = jQuery("input[type=checkbox]:checked");
var toProcess = checkedBoxes.size();
checkedBoxes.each(function() {
jQuery.post('somepage.php',{...},function(results) {
numProcessed++;
if(numProcessed == toProcess) {
jQuery("#saving-message").remove();
jQuery("#feedback-panel").text('Successfully processed all selections.');
}
}
}
There is only one thread in JavaScript so every function that want to be execute is put in stack and have to wait until all others are execute. In your case "each" is the first function in the stack, so every callback function have to wait and will be execute in the order they put on the stack.
After all "numProcessed == toProcess" could only one time be true.
The rx.net team has introduced rx for javascript. Reactive extension are for asynchronous programming. they have also written for rxjs for jquery too. My be that suite your need http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx