Thread Safe JavaScript Callback Functions with Node Addon API (C++)

Save a reference to a JavaScript callback function for later use and make sure it runs on the main thread

Jake Cyr
2 min readSep 4, 2021
Computer with code on screen and someone foot up on the desk next to it

When working on a C++ Node addon project, I found there are very few examples of how one could save a reference to a JavaScript callback in a Node addon for later use.

After reading through the Node Addon API documentation I found the Napi::ThreadSafeFunction class was the best solution. The Napi::ThreadSafeFunction as its name suggests, makes sure that when you go to run the callback in future, it is running on the same thread as the JavaScript environment (the main thread) as opposed to on a separate thread that can’t communicate with the rest of the application.

To get started, you can create a global variable (or class property if you’re working with a class) with the type Napi::ThreadSafeFunction. Then, let’s add our function to set the callback giving us the following:

As you can see, I also added another variable callbackWasSet to track if the function was called successfully so we know if the callback if defined or not when we go to call it. This can probably be done a better way by checking the ThreadSafeFunction instance before calling it. I also added some guards to the function to check the parameter type which are optional.

Next, let’s add our function that is going to trigger our saved callback:

On the threadSafeCallback you can see we trigger a NonBlockingCall with a referenced lamba function that receives the current env and a jsCallback to execute. Line 11 is what actually executes our saved callback function. This runs the JavaScript callback that was sent into the SetCallback method on the main thread.

Now we can add an Init function to export our SetCallback and TriggerCallback functions to be used by our JavaScript application giving us the following fully working file (lines 46–56 are the ones that were added from previous examples above):

After you build your project and import it into your JavaScript file, you can run it as follows:

The full project can be found on GitHub:

https://github.com/jakecyr/Node-Addon-API-Callback-Example

If you have any questions, feel free to leave a comment and don’t forget to leave a like (clap) if you liked this article so I know to make more in the future.

--

--

Jake Cyr

Proficient in AI and cloud tech, advancing systems development with a commitment to continual growth.