I am wondering where the connection should be released after using it, i have seen couple of options for that:
pool.getConnection(function(err, conn){
//conn.release() // should be placed here (1)?
conn.query(query, function(err, result){
//conn.release() // should be placed here (2)?
if(!err){
//conn.release() // should be placed here (3)?
}
else{
//conn.release() // should be placed here (4)?
}
//conn.release() // should be placed here (5)?
});
//conn.release() // should be placed here (6)?
});
Or maybe should it be released both error and non error cases?
The correct place is either #2 or #5.
You want to release the connection when you are done using it.
#6 would be wrong because query() is asynchronous, so it would return right away before the connection is done with the query and before the callback fires. So you'd be releasing the connection before you are done with it.
#5 is correct because the callback has fired and you have done everything you are going to do with it. Note that this assumes that you do not use return to exit the function before that point. (Some people do that in their if (err) blocks.)
#2 is also correct if you aren't using the connection anywhere inside the callback. If you are using it in the callback, then you don't want to release it before you are done using it.
#3 and #4 are incorrect unless you use both of them. Otherwise, you are only releasing the connection in some situtations.
And #1 is incorrect because you haven't used the connection yet.
Related
My question is: Is it okay to pass a promise to the first argument of .then? (Assuming that I'm not interested in the returned value of the previous promise and I just want to chain promises together).
Someone told me that if I do this, a new promise will be created
implicitly (unnecessarily), and I might face issues handling errors
bellow in the promise chain.
I know that if you don't explicitly return a promise in an async method the result will be implicitly wrapped. In this case, .then should not wrap the argument in a promise since the argument is already a promise :/
Example:
async function asyncFunc() {
//async function (return Promise)
}
// I know this is okay
somePromise.then(() => asyncFunc());
// BUT... is this okay?
somePromise.then(asyncFunc());
Is it okay to pass a promise to the first argument of .then?
Yes.
Someone told me that if I do this, a new promise will be created implicitly (unnecessarily)
Promise.prototype.then() returns a new promise either way.
// BUT... is this okay?
somePromise.then(asyncFunc());
No, it is more or less the same as:
const p = asyncFunc()
somePromise.then(p);
You execute the function before somePromise actually resolves. What you probably want instead is somePromise.then(asyncFunction). This will properly chain the promises after each other.
Someone told me that [...] I might face issues handling errors bellow in the promise chain.
No. This does not change the behaviour of the promise chain as long as long as there is a catch at the end of the chain.
I created the code below which generates the error: Uncaught TypeError: Cannot read property 'done' of undefined. I think I understand what's happening here, def() isn't a deferred until the timeout expires and the .done tries to run straight away, but what I don't understand is if this doesn't work, why do deferreds work at all? How does .done ever know that the code in front is a promise/deferred given that it may not have resolved yet? Please explain syntax that will make it work, because this is doing my head in.
To put it bluntly I wish that .done would just shut up and wait like it's meant to (I understand that it would have to be a method of all objects and wait until they've resolved even if it's not to a deferred, but if you've typed .done why wouldn't you want that?). Or does it work that way, but I just don't know how to use it properly?
Please don't just refer me to an existing guide/post on jquery deferred unless it explicitly resolves my confusion.
Thanks.
jsfiddle here
function def() {
d = new $.Deferred;
setTimeout(function(){
d.resolve();
return d;
},1000)
}
def().done(function(){
console.log('test');
});
You have to return the promise value from def() itself, not from the setTimeout().
function def() {
var d = $.Deferred();
setTimeout(function(){
d.resolve();
},1000)
return d;
}
def().done(function(){
console.log('test');
});
Returning a value from setTimeout() doesn't do anything. def() has long since finished executing (and returning nothing) and the return value from setTimeout() just goes back into part of the system runtime that calls timer callbacks and is ignored.
I also made a couple other corrections:
Declared d as a local variable (not an implicit global) by putting var in front of its declaration.
Changed the creation of the deferred to $.Deferred(). While, I think the new construction might work, that isn't how jQuery has documented its usage.
When you reach the size limit for your web sql store, Mobile Safari (and the Android browser) will prompt you to increase the storage size. Once that happens, neither the transaction, onSuccess callback or onError callback is executed. I cannot seem to catch any exceptions here either, so how am I supposed to handle prompts for increased storage?
All the operations are async, so I can only think of setting a timeout and checking if the transaction completed after some time has gone. Which of course is a nasty, bug-ridden hack. And in addition to that, I have to re-do the transaction to actually check if the space was increased or not.
Fiddle for verifying on mobile browser
// open the jsfiddle in safari
// refuse when prompted to increase space to show the bug
db.transaction(function (tx) {
tx.executeSql("INSERT INTO key_value(key, value) VALUES(?,?);", ["mykey", buildBigString(3*Math.pow(10,6))], function (tx, result) {
// will never be called
done();
}, function (tx, error) {
// will never be called
done();
});
});
The problem with the above code was basically that I was missing an error callback for the transaction wrapping the sql insertion. For more info on generally how to actually handle user prompts, see this elaborated blog post on the matter.
From the specification on the Asynchronous Database API
void transaction(in SQLTransactionCallback callback,
in optional SQLTransactionErrorCallback errorCallback,
in optional SQLVoidCallback successCallback);
No example code showed this, and so I kept on assuming the transaction method was used without callbacks.
So instead of writing
db.transaction(function (tx) {
// if this prompts the user to increase the size it will not execute the sql or run any of the callbacks
tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')', onComplete, onError );
});
Do this
// Note the reverse order of the callbacks!
db.transaction(function (tx) {
// this will prompt the user to increase the size and the sql will not be executed
tx.executeSql('INSERT INTO foo (id, text) VALUES (1, createReallyBigString('4MB')');
}, onError, onComplete );
Previously I was PHP developer so this question might be stupid to some of you.
I am using mysql with node js.
client.query('SELECT * FROM users where id="1"', function selectCb(err, results, fields) {
req.body.currentuser = results;
}
);
console.log(req.body.currentuser);
I tried to assign the result set (results) to a variable (req.body.currentuser) to use it outside the function, but it is not working.
Can you please let me know a way around it.
The query call is asynchronous. Hence selectCb is executed at a later point than your console.log call. If you put the console.log call into selectCb, it'll work.
In general, you want to call everything that depends on the results of the query from the selectCb callback. It's one of the basic architectural principles in Node.JS.
The client.query call, like nearly everything in node.js, is asynchronous. This means that the method just initiates a request, but execution continues. So when it gets to the console.log, nothing has been defined in req.body.currentuser yet.
You can see if you move the console log inside the callback, it will work:
client.query('SELECT * FROM users where id="1"', function selectCb(err, results, fields) {
req.body.currentuser = results;
console.log(req.body.currentuser);
});
So you need to structure your code around this requirement. Event-driven functional programming (which is what this is) can be difficult to wrap your head around at first. But once you get it, it makes a lot of sense.
I am trying to dispatch an event but not sure when I should do it to get the right results. The first event "submitClicked" is in the right spot and works great. However, the second event "dataReady" seems like it might be a problem.
I need it to be dispatched after this.compiledFormData is set.
Does AS3 wait for each line of code in a function to be executed before moving on to the next line?
// --------------------------------------------------------------------
public function submitForm()
{
//dispatch an event
var cEvt:FormRendererEvent = new FormRendererEvent( "submitClicked" );
cEvt.customMessage = "Started Submitting Form Data";
dispatchEvent(cEvt);
this.compiledFormData = JSON.encode(this.compileFormData());
var cEvt:FormRendererEvent = new FormRendererEvent( "dataReady" );
cEvt.customMessage = "Data is ready to be used";
dispatchEvent(cEvt);
}//end function
Yes, in AS3 each line must complete before the next line can run. When you dispatch events though, they will go off and do their own thing. So, your "main" code might complete, meanwhile your dispatched events could still be processing.
Each line of code is executed sequentially yes, but whether the implementation of the invoked API does something asynchronous is dependent on what API you're calling.
In this case JSON.encode is a synchronous operation and therefore will complete fully before the next line of code is executed.