How can I wrap up an asynchronous call to behave synchronously?
Currently, this is how I perform a query using node-mysql
client.query( sql, function( error, result ) {
console.dir( result );
});
I would like to do t开发者_C百科his synchronously, something like this
var result = client.querySync( sql );
console.dir( result );
I understand why blocking in node is bad, but I'm (almost) grown up enough to know when it's okay and when it's not. I only intend to make synchronous calls at the initialisation stage, outside of any event loops.
Does anybody know how I can achieve this please?
Edit...
Something along the lines of...
client.querySync = function( sql )
{
var called = false;
var result;
while ( typeof result == 'undefined' ) {
if ( ! called ) {
called = true;
this.query( sql, function( error, _result ) {
result = { error: error, result: _result };
});
};
}
return result;
};
Your proposed solution (in your edit) won't work because you never give up the thread (so the callback can never be called, so the variable can never be set, so your loop never breaks). Node is not multi-threaded - there is only ever one thread executing javascript at any one time. There is no way to yield that thread except by returning from whatever code is running.
So, you can't do what you want to do. You could try to use some of the solutions that re-write your sync code into async behind the scenes, but I've personally found that approach isn't really worth the effort -- that's it better to just bite the bullet and just do everything with callbacks (over time the pain subsides :).
Don't. Learn to do asynchronous programming.
Use flowcontrol like futuresJS for keeping your code organised
My guess is that you could have add queueing system like an array of commands within the 'client' of commands that is added to and then looped through by every call to the syncronous method of your client and also by end of any 'blocking' action.
so:
client.mySyncMethod = function(command, callback)
{
commandArray.push({command, callback});
runCommands();
}
client.runCommands = function()
{
for (var i in commandArray)
{
// run command
}
}
What is the problem you are running into?
Your sample is procedural in nature due to the callbacks. If you don't want anything to run before all of this stuff is done then only execute the main code after all your callbacks finished:
client.query( sql, function( error, result ) {
console.dir( result , function () {
//now start your app code
} );
});
Everything is still async and you are not fighting your environment while nothing will happen unless the procedural startup is done.. Wrap the whole thing in a simple function with the callback as an argument and you should be good to go.
As for doing this all synchronously: Node.js clearly does not allow you to halt the event-loop. That concept is not there and you simply can't. You can write your querySync as a chain of callbacks to make it behave synchronously.. but it won't be pretty.
There's no way in node.js making asynchronous code behave like synchronous code.
精彩评论