Microsoft Azure
Published in

Microsoft Azure

Promises, Node, Tedious, Azure SQL. Oh My!

If you are new to Node.js like I am, using Tedious to access Azure SQL can be challenging at the beginning. My understanding is that Tedious, while being fully asynchronous, doesn’t support nor Promises nor the more modern async/await pattern. Tedious, in fact, uses to execute asynchronous code and so a bit of work is needed to make it compatible with Promises.

At the end of the day is just a few lines of code, but the process of discovering those two lines can be quite long and sometime frustrating. There is no statement anywhere that shows how to properly do that. I think that’s due to the fact that once you get the grasp of Promises it became absolutely obvious….but if you haven’t got to that point, you’re left in the dark.

Well, let’s shed some light then, and fix this hole in the shared knowledge book that is the internet!

Encapsulate usage of Tedious

To avoid writing the same code again and again, you probably want to encapsulate the business logic that executes a SQL command into a function. Something — in theory — like the following

executeSQL = function(query, params) {
var result = null;

const conn = new Connection(...);
conn.on('connect', err => { ... invoke req ... });

const req = new Request(query, err => { return result });
req.on('rows', columns => { ... build result ... });


After the connect() method has been successfully called, the event will happen. From there, the created Request can be executed. The request will generate a row event that allows you to get the result coming in from Azure SQL, and process and store it into a variable of your choice.

The challenge now is: how do we return the variable with the resultset to the caller?

Writing something like

queryResult = executeSQL(...)

will work but will not produce any result, as the content of executeSQL function will be executed asynchronously. This means that, even if we would add a return result; to the function body, just before it ends, the only thing that will be stored into our queryResult variable is...nothing. If fact, the return statement materially switches execution back to the caller, but at that time the result variable will still be empty as it is very unlikely that Azure SQL would have returned results so quickly. Azure SQL can easily return data in milliseconds, but in this case we're taking about microseconds or less, and just the network roundtrip is more than that.

So what we need to do is to make sure that we start to use the variable result and its contents only when they are available.

That’s exactly what a Promise do. Taken from aforementioned and linked documentation:

Create the Promise Wrapper

With that clear in our mind, it now become obvious that we need to wrap our reusable method in a Promise, instead of a classic function. The code will then look like the following:

const executeSQL = (query, params) => new Promise(
(resolve, reject) => {

...function body...

That’s easy right? There are two callbacks that we now have access to

  • resolve: to do something when the everything worked as expected and result is ready to be processed by the caller
  • reject: when something didn't work and result is not available.

Given that we know that the Request object also supports a callback to allow us to execute some code once the resultset has been fully sent by Azure SQL, the original code will now look like this:

We know we can safely use the result variable here, which was populated inside the row event handler, as Tedious doc assure us that:

Use the Promise, Luke!

Now that we have our Promise, let’s use it.

Somewhere in our code we want to call the executeSQL function and get the result into a variable of our choice. Instead of writing something like,

const result = executeSQL(query, params);

we need to do something like this instead:

executeSQL(query, params)
.then(ok => {
...process result here...
.catch(err => {
...handle errors here...

In the then code block you can use the result, now available in the ok variable.


That’s, done! All will now work smoothly and nicely.

I really hope this article helps to clearly resolve this challenge once and for all. I would have loved to have such article right away, it would have saved hours and hours in my life. Now I have a quite good understanding on Promises, and — yeah — everything is trivial now, but reaching this point has been a painful voyage. Coding should be joy, not pain! Frustration is ok and also helpful sometimes, but I felt that here was way too much. Well, the table is turned now, this article is here to bring joy back to the game!

Until next time, have fun.

Wait! I Want the Source Code!

Uh yeah, of course, source code! It’s here: Todo Backend Implementation with Azure Functions, Node and Azure SQL and more specifically the code described in the article is here.

As an exercise I took the chance to implement a fully working back-end API for the Todo MVC app, following the Todo Backend API specifications. Love how everything amazingly works well together like a couple of LEGO bricks.



Any language. Any platform. Our team is focused on making the world more amazing for developers and IT operations communities with the best that Microsoft Azure can provide. If you want to contribute in this journey with us, contact us at

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Davide Mauri

Data Geek, Storyteller, Developer at heart, now infiltrated in Azure SQL product group to make sure developers voice is heard loud and clear. Heavy Metal fan.