How to call a nodejs async function from napi native code and wait until the async promise is resolved

757 Views Asked by At

I'm trying to call a nodejs async function from c++ that returns a promise that will be fufilled later using napi

Napi::Value napiStatus = this->nodejsFunction.Call(someArgs)

I want to wait until the promise is finished and get napiStatus to be filled out with the resolved value rather than the handle to the promise. Is there any way to do this? I've gotten this to work when the function is not async and simply returns a value but my current requirements won't let me do that.

Here's an example function in JS that I want to call

function timedTest() {
  let timerExpired = new Promise((resolve,reject)=>{
    setTimeout(()=>{
      resolve(1);
    },3000)
  })
  return timerExpired;
}

I want napiStatus to be the resolved value of 1 (after napi conversions).

1

There are 1 best solutions below

0
Criminal_Affair_At_SO On

You have to do the same as if you were doing it from JavaScript: call the .then() method of the Promise and register a callback.

Here is the complete example:

Napi::Value ret = asyncFunction.Call({});
if (!ret.IsPromise())
  throw Napi::Error::New(env, "your function did not return a Promise");
Napi::Promise promise = ret.As<Napi::Promise>();

Napi::Value thenValue = promise.Get("then");
if (!thenValue.IsFunction())
  throw Napi::Error::New(env, "Promise is not thenable");
Napi::Function then = thenValue.As<Napi::Function>();

Napi::Function callback = Napi::Function::New(env, Callback, "cpp_callback");
then.Call(promise, {callback});

The Callback function will receive the data from the resolved Promise:

Napi::Value Callback(const Napi::CallbackInfo &info) { 
  printf("Callback called\n");
  printf("Data: %s\n", info[0].ToString().Utf8Value().c_str());
  return info.Env().Null();
}