WebSQL and Javascript Order of Operation - javascript

My application is using the javascript webSQL and I am having some issue with the order of command execution. No matter what order my code is in the querys get executed last. For example in the following code 2 will be alerted before 1:
db.transaction(
function (transaction) {
transaction.executeSql(
'SELECT * FROM contacts WHERE id = ?;',
[id],
function (transaction, result) {
alert("1");
if (result.rows.length != 0) {
user = result.rows.item(0).name;
} else {}
},
errorHandler);
});
alert("2");
message = id + '%1E' + name;
Any ideas why this is happen?

When do you alert("2"), you haven't finished the transaction, so the 2nd function you pass to it has not been called. Since it's the success handler I assume, it will be called after the transaction has completed successfully. The third argument would be the code snippet to execute when the query failed, only if it failed.
Anything outside of the event handler code is executed when the page has loaded enough content to execute the javascript. Note that the entire page need not load to execute alert("2"), just enough of the JS. Since these statements are soooo close together, there is bascially 0 chance that the transaction will ever complete before the alert("2") statement is reached and executed.
However, if you had enough code between alert("2") and db.transaction(...), it's possible (in what is called a race condition) that the callback could be executed before the alert(2) code.
You want to be careful with event handlers in this case, although it depends on what your success handler does. If it modifies the page DOM, then I would highly recommend wrapping the db.transaction() and surrounding code) in an event handler that is bound to the page loading.

This isn't an answer to your question, but I thought I should give you a warning about webSQL.
As of 18 November 2010, W3C had announced that they have deprecated the Web SQL Database recommendation draft and will no longer maintain it.
So while it may WORK in browsers at the moment, I wouldn't rely on it for the future.

Related

Trouble understanding doc().get() in firebase

I am having a bit of trouble understanding why my code is not working. I am trying to read data from firebase inside a react-native project. I can read it just fine, but I cannot set the data to any variables.
This is my code here.
let tmp;
let userRef = firebase.firestore().collection("Users");
userRef.doc(this.state.FirstName).get().then((document) => {
tmp = document.data().FirstName;
alert(tmp);
})
.catch((errorMsg) => {
alert(errorMsg);
})
alert("tmp Data: " + tmp);
};
The problem is that if I alert tmp inside of the function it shows the FirstName variable as expected. But when I alert tmp outside of the function, it shows undefined. I just cannot seem to wrap my head around why this is not working, if anyone could tell me what I'm doing wrong here, I would much appreciate it.
This is totally normal. It happens because if you put the alert outside the block, then it will get executed before the block, with tmp being uninitialized. The code that gets the FirstName from the database (the get() function) executes some code in another thread and your original thread continues without waiting for it to finish. When that another thread finishes execution, the code inside the block gets executed. You can verify this behavior by adding alerts before, inside, and after the block to see the order of the execution. To know more, read about asynchronous operations and promises.
Why all of this? Why does get() execute some code in another thread? Briefly, because it uses the network to access the Firebase database and it may take some time before getting a response back. If get() executes the 'networking code' in the same calling thread, then calling it from the main thread (the UI thread) will make your UI unresponsive until the response returns back. So, instead, get() dispatches the 'networking code' to another thread and returns a promise object immediately even before the 'networking code' finishes execution. You use that promise object to specify what you want to do with the result whenever it arrives. This way, the calling thread continues execution and does not need to wait, and in the case where the calling thread is the UI thread (which is usually the case), it means that your UI is always responsive.

Force Chrome to check if a $.ajax call has finished?

Good afternoon guys -
Is there a well known way to check if a $.ajax call has finished?
-- FOR INSTANCE --
Let's say I'm using a $.ajax call to load in a large number of leaflet polygons from a .geojson file (asynchronously as a layer group). Under normal circumstances, this happens almost immediately - but the user has elected to load a large job this time around. The user has assumed that the set of polygons has been loaded and attempts to do something with this group of layers prematurely - only to find that nothing happens (the layer group doesn't actually exist yet in the browser).
My intuition (I'm new to web development) is to have some sort of global flag that's set for the dependent algorithm to check. We would set the flag prior to loading the layers, and then change it to some other value in the .done({}) section of the $.ajax call.
-- UPDATE --
I've reworked the code to allow users to choose whether or not they wish to retry the request, and also force the browser to wait some time before retrying the request.
However, I've also found the the issue seems to be with Chrome. Firefox appears to be able to handle the $.ajax.always callback as soon as it finishes (in other words, the $.ajax.always callback will interrupt the regular flow of javascript).
Chrome appears to block the $.ajax.always callback and only lets it execute after all other javascript has finished running (no interrupt).
This particular question stemmed from a debug case that automated user input from within a loop - and since Chrome doesn't call the $.ajax.always callback until the current process is complete, the process isn't marked as completed.
Example Code:
procBox = []; // Global scope, stands for Process Box
function loadPolygons() {
procBox["loadPolygons"] = "running";
$.ajax({
// ajax things here
}).done(function() {
procBox["loadPolygons"] = "done";
}).fail(function() {
// failure stuff here
});
}
function dependentFunction() {
if procBox["loadPolygons"] === "done") {
// The meat of the function (dependentFunction things here)
} else {
// Backup case that allows the browser to retry the request
/* --
* If this fires, the server is still trying to process the
* ajax request. The user will be prompted to retry the request,
* and upon agreement, the function will be called again after
* 1 second passes.
*/
var msg = "Oops! It looks like we're still fetching your "
+ "polygons from the server. Press OK to retry.";
if (confirm(msg)) {
setTimeout(dependentFunction, 1000);
}
}
}
This approach seems to work well in Firefox - the alert() stops JavaScript execution and gives it a chance for the .done({}) callback to occur. But for some reason, the while loop never allows the .done({}) callback to complete in Chrome!
Does anyone know of a better approach for this than using flags or async: false?
I appreciate any answers and knowledge out there!
There are numerous ways to do :
as already sugegsted you can use
since you use jQuery, you can use custom events https://learn.jquery.com/events/introduction-to-custom-events/:
$(document).on("myajax:done", function(){ dependentFunction();})
$.ajax({...}).done(function(){
$(document).trigger("myajax:done")
});
or even global ajax events
https://api.jquery.com/category/ajax/global-ajax-event-handlers/
but really consider why not to do something like
procBox = {onLoadPolygons:dependentFunction}; // Global scope
function loadPolygons() {
$.ajax({
// ajax things here
}).done(function() {
procBox["onLoadPolygons"]();
}).fail(function() {
// failure stuff here
});
}
function dependentFunction() {
alert("Please wait for the polygons to load");
dependentFunctionThings();
}
function dependentFunctionThings(){
// Do dependent function things...
}
UPD:
if you ensist on your structure, and still want to use blocking function
use setInterval to perform check
function dependentFunction() {
var h = setInterval(function() {
if (procBox["loadPolygons"] == "done") {
clearInterval(h);
// Do dependent function things...
}
}, 100);
}
Or wrap it up into a Promise (http://caniuse.com/#feat=promises)
function dependentFunction() {
(new Promise(function(resolve) {
var h = setInterval(function(){
if (procBox["loadPolygons"] == "done") {
clearInterval(h);resolve();
}
}, 100);
})).then(function(){
// Do dependent function things...
});
}
But I still believe that something wrong in your structure
From the docs :
.ajaxComplete()
Whenever an Ajax request completes, jQuery triggers the ajaxComplete event. Any and all handlers that have been registered with the .ajaxComplete() method are executed at this time.
http://api.jquery.com/ajaxcomplete/

Function running before the outer one?

I have this server in Node.js using socket.io.
I have a function
function updatePoints(){
pool.getConnection(function(err, connection) {
connection.query("SELECT * FROM `users`", function(error, rows) {
//here it fetchs the users' points and emit to their respective sockets
});
connection.release();
});
}
Alright, when I call this function inside another one, it seems to run before the codes that come before it.
Here:
function(){
connection.query('UPDATE `users` SET '...});
connection.query('UPDATE `users` SET '...});
updatePoints();
}
This second function is when a user is donating points to another one, so I decrease the points from the donor and increase the receiver's points.
Funny thing that when the function is called it emits for the donor just like I want it to do. The donor sees his points updating real time, while in the receiver's side he can't see it, unless the other one donates him points for a second time, then he sees the first donation going on. If the function is running before if should, how can I make it work?
connection.query() is asynchronous. That means that calling it just starts the operation and it then runs in the background. Meanwhile, the next line of Javascript runs right away while the connection.query() is going on in the background. So, if you do:
connection.query(...);
someFunction();
Then, as you have discovered, someFunction() will execute before connection.query() finishes.
The solution is to sequence your work using the completion callback of the connection.query() operation by putting anything that should happen after the query completes inside the callback itself.
connection.query(..., function(err, rows) {
// execute some function after the query has completed
someFunction();
});
This can be extended to more levels like this:
connection.query(..., function(err, rows) {
// execute another query after the first one
connection.query(..., function(err, moreRows) {
// execute some function after both queries have completed
someFunction();
});
});
// code placed right here will execute BEFORE the queries finish
Now standard in ES6 and available in many libraries, the concept of promises can also be used to coordinate or synchronize asynchronous operations. You can read more about promises in zillions of places on the web. One introductory explanation is here on MDN.
I don't really understand what you are trying to say but it seems like a closures problem.
If that is the case may be this
How do JavaScript closures work? can help you out.
It explains closures in detail.

WebSQL transaction works in the console, not in code

I'm trying to write a Sencha Touch 2.0 WebSql proxy that supports tree-data. I started from tomalex0's WebSql/Sqlite proxy. https://github.com/tomalex0
When modifying the script I ran into a strange debugging issue:
(I'm using Chrome 17.0.963.78 m)
The following snipped just got jumped over. The transaction never takes place! But when I set a breakpoint above or below and I run the same code in the console, it does work!
dbConn.transaction(function(tx){
console.log(tx);
if (typeof callback == 'function') {
callback.call(scope || me, results, me);
}
tx.executeSql(sql, params, successcallback, errorcallback);
});
The blue log you can see, the green log is from the success handler. When the query would be performed there would be exactly the same log above (it's a SELECT * FROM ...; so when performing multiple times without changing data I would expect the same result)
I found out that when I add the code block to the watch expressions it also runs.
It isn't being skipped over. It is being scheduled, but not being executed till much later due to the asynchronous nature of the request:
http://ejohn.org/blog/how-javascript-timers-work/
Since the code is being executed synchronously to make the asynchronous call it will delay the call till after the synchronous code has been executed, due to the single threadedness of javascript.

Ajax event handler does not update variables?

I'm having issues getting a variable declared in an .click function to be updated in a Get function within the click function. I've gathered that even though the variable has the same name, within the Get function it is really declaring it anew.
I've tried to find examples helping me, but it appears to me that the Get method is such a specialized function that the examples didn't seem to apply.
I would like the value of 'SettingContentToEdit' to get updated with information retrieved with the Get function.
Below is the code.
Thank you for your help!
$(".cellSetting").click(function () {
var clickedClass = $(this).attr("class");
var clickedItemID = $(this).attr("id")
var SettingContentToEdit = "not changed";
var JSONSend = {
'ItemName': clickedItemID, //send the item name so the model knows which one to pull up!
'ItemSetting': clickedClass
};
$.get(
'/Home/getItem',
JSONSend,
function (data) {
// $('#dialog').html(data.ItemSettings[data.SettingToEdit]);
SettingContentToEdit = data.ItemSettings[data.SettingToEdit];
alert(SettingContentToEdit); //returns the correct info
}
);
alert(SettingContentToEdit); //returns "not changed"
});
Your issue is that your ajax call is asyncronous. The success handler for the get() function is called some time after your click handler and the alert() has already completed. You can refer to the local variables in your success handler, but the code that follows the success handler executes BEFORE the success handler does.
This is because your get() operate is asynchronous. Calling it just STARTS the networking operation and then your javascript execution continues (while the networking operation works in the background). After starting the networking operation, your alert() is called. Then, some time LATER, the Ajax call completes and the success handler is executed.
This is a very common mistake and has indeed been asked and answered hundreds (if not thousands) of times here on SO (I've personally probably answered 20-30) so you are not alone in missing this understanding at first.
If you want to use the results of the ajax operation, then you need to put the code that does that either in your success handler or put it in a function that you call from your success handler. You cannot put it after the get() function because it will execute too soon before the results are known.
AJAX is asynchronous. If you check SettingContentToEdit a second or so later than you are doing, you'd see the value has updated.
Either put your code inside the get function (where you have your alert showing the correct value) or make the request synchronous (you'll have to look up the jQuery docs because I don't use jQuery).

Categories

Resources