如何使用返回Promises的NAPI创建异步函数

西瓦姆·库马尔

我正在尝试使用NAPI创建节点模块。我必须创建一个返回诺言的异步函数。我不希望testasynfunction会阻止NodeJS事件循环。do_something_asynchronous是一个同步函数。

napi_deferred do_something_synchronous(napi_env env,napi_deferred deferred){
  printf("\n3) Function called");
  //napi_deferred deferred;
  napi_value undefined;
  napi_status status;

  // Create a value with which to conclude the deferred.
  status = napi_get_undefined(env, &undefined);
  if (status != napi_ok) return NULL;
  sleep(5);
  // Resolve or reject the promise associated with the deferred depending on
  // whether the asynchronous action succeeded.
  if (false) {
    printf("\n5) Success\nXXXXXXX");
    status = napi_resolve_deferred(env, deferred, undefined);
  } else {
    printf("\nReject");
    status = napi_reject_deferred(env, deferred, undefined);
  }
  if (status != napi_ok) return NULL;

  // At this point the deferred has been freed, so we should assign NULL to it.
  deferred = NULL;
}

//Function will be called from the js 
napi_value testasynfunction(napi_env env, napi_callback_info info){
  printf("XXXXX Hello \n");
  napi_deferred deferred;
  napi_value promise;
  napi_status status;
  // Create the promise.
  status = napi_create_promise(env, &deferred, &promise);
  if (status != napi_ok) return NULL;
  printf("\n1) Calling function to do something");
  do_something_synchronous(env,deferred);
  //std::async(do_something_asynchronous,env,deferred);
  printf("\n2) Returning Promise");
  return promise;
}
napi_property_descriptor testasync = DECLARE_NAPI_METHOD("testasyn", testasynfunction);
  status = napi_define_properties(env, exports, 1, &testasync);
  assert(status == napi_ok);

NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

问题:1)我如何才能异步运行do_something_synchronous,以便nodejs事件循环不会被阻塞并返回诺言?

萨蒂扬

以下代码段是此异步操作的关键组件。napi_create_async_work()函数分配工作对象,我们可以指定工人处理函数,比如在我们的例子ExecuteMyPromise1()(长时间运行或处理繁重的任务可以用它来部署)。此函数将作为工作池线程的队列,并且将与node.js主事件循环线程并行地异步执行

到目前为止,一切看起来都还不错,当ExecuteMyPromise1函数计划直接从工作线程与JavaScript层交换结果时,问题就会出现。通常,只能从本机插件的主线程调用任何JavaScript操作然后,为了进行结果交换,我们必须使用另一个将从主线程调用的本机函数。这就是为什么我们使用CompleteMyPromise1函数处理程序(如果还通过此函数完成的任何最终清理活动)的原因。当异步逻辑完成或取消时,将从主事件循环线程中调用此本地函数。

// The function called by javascript to get a promise returned.
napi_value MyPromise1(napi_env env, napi_callback_info info)
{

  // -- -- -- --
  // -- -- -- --

  // Create a promise object.
  status = napi_create_promise(env, &promDataEx->deferred, &promise);
  if (status != napi_ok)
  {
    napi_throw_error(env, NULL, "Unable to create promise.");
  }


  // -- -- -- --
  // -- -- -- --

  {
    // Create the async function.
    napi_value resource_name;
    napi_create_string_utf8(env, "MyPromise1", -1, &resource_name);
    napi_create_async_work(env, NULL, resource_name, 
        ExecuteMyPromise1, CompleteMyPromise1, 
        promDataEx, &promDataEx->work);
    napi_queue_async_work(env, promDataEx->work);
  }


  return promise;
}
// Execute the asynchronous work.
void ExecuteMyPromise1(napi_env env, void *data)
{
    prom_data_ex_t *promDataEx = (prom_data_ex_t *)data;

    // Calculate prime count
    promDataEx->PrimeCount = CPrimeCount( promDataEx->x, promDataEx->y );

    // Set the status as asynchronous_action is success
    promDataEx->asynchronous_action_status = 0;
    //sleep(3);
}
// Handle the completion of the asynchronous work.
void CompleteMyPromise1(napi_env env, napi_status status, void *data)
{
    napi_value rcValue;

    prom_data_ex_t *promDataEx = (prom_data_ex_t *)data;

    napi_create_int32(env, promDataEx->PrimeCount, &rcValue);

    // Resolve or reject the promise associated with the deferred depending on
    // whether the asynchronous action succeeded.
    if ( promDataEx->asynchronous_action_status == 0) // Success
    {
        status = napi_resolve_deferred(env, promDataEx->deferred, rcValue);
    }
    else
    {
        napi_value undefined;

        status = napi_get_undefined(env, &undefined);
        status = napi_reject_deferred(env, promDataEx->deferred, undefined );
    }
    if (status != napi_ok)
    {
        napi_throw_error(env, NULL, "Unable to create promise result.");
    }

    napi_delete_async_work(env, promDataEx->work);
    free(promDataEx);
}

这里是完整的示例代码https://github.com/msatyan/MyNodeC/blob/master/src/mync1/MyPromise1.cpp

JavaScrip调用是TestPromiseWithAsync()https://github.com/msatyan/MyNodeC/blob/master/test/TestExtensions.js

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用Meteor.loginWithPassword()登录后创建异步函数以返回用户状态

来自分类Dev

Promises 中的异步函数

来自分类Dev

如何在范围内使用异步函数返回

来自分类Dev

如何使用Promises编写异步循环?

来自分类Dev

我在异步函数中使用Promises是否正确?

来自分类Dev

异步函数JS问题。我可以使用Promises吗?

来自分类Dev

您如何为非返回/并行异步函数创建存根/间谍?

来自分类Dev

如何从异步函数返回扩展的Promise实例?

来自分类Dev

如何从异步函数返回值

来自分类Dev

如何在.map中返回异步函数?

来自分类Dev

如何修复返回`undefined`的异步函数?

来自分类Dev

如何从异步函数返回多个值以在另一个函数中使用

来自分类Dev

使用异步命令从函数返回值

来自分类Dev

使用内部函数返回的异步数据返回外部函数的promise

来自分类Dev

如何异步使用PHP函数

来自分类Dev

使用异步库从异步函数获取返回值

来自分类Dev

如何从返回Task <T>的异步函数返回错误

来自分类Dev

如何获取返回承诺的异步函数的返回值

来自分类Dev

如何获取返回承诺的异步函数的返回值

来自分类Dev

JavaScript:如何在异步内部函数内部返回外部函数?

来自分类Dev

如何从异步函数创建同步函数以实现向后兼容

来自分类Dev

异步函数自动返回

来自分类Dev

如何使用函数使用异步等待

来自分类Dev

异步等待如何使用返回值

来自分类Dev

如何使用apache wink返回异步响应?

来自分类Dev

如何使用async / await异步创建DispatcherObject?

来自分类Dev

如何使用异步回调编写异步递归walkdir函数

来自分类Dev

如何使用异步函数异步侦听 Firestore 中的值?

来自分类Dev

如何在异步函数中使用“ yield”?

Related 相关文章

  1. 1

    如何使用Meteor.loginWithPassword()登录后创建异步函数以返回用户状态

  2. 2

    Promises 中的异步函数

  3. 3

    如何在范围内使用异步函数返回

  4. 4

    如何使用Promises编写异步循环?

  5. 5

    我在异步函数中使用Promises是否正确?

  6. 6

    异步函数JS问题。我可以使用Promises吗?

  7. 7

    您如何为非返回/并行异步函数创建存根/间谍?

  8. 8

    如何从异步函数返回扩展的Promise实例?

  9. 9

    如何从异步函数返回值

  10. 10

    如何在.map中返回异步函数?

  11. 11

    如何修复返回`undefined`的异步函数?

  12. 12

    如何从异步函数返回多个值以在另一个函数中使用

  13. 13

    使用异步命令从函数返回值

  14. 14

    使用内部函数返回的异步数据返回外部函数的promise

  15. 15

    如何异步使用PHP函数

  16. 16

    使用异步库从异步函数获取返回值

  17. 17

    如何从返回Task <T>的异步函数返回错误

  18. 18

    如何获取返回承诺的异步函数的返回值

  19. 19

    如何获取返回承诺的异步函数的返回值

  20. 20

    JavaScript:如何在异步内部函数内部返回外部函数?

  21. 21

    如何从异步函数创建同步函数以实现向后兼容

  22. 22

    异步函数自动返回

  23. 23

    如何使用函数使用异步等待

  24. 24

    异步等待如何使用返回值

  25. 25

    如何使用apache wink返回异步响应?

  26. 26

    如何使用async / await异步创建DispatcherObject?

  27. 27

    如何使用异步回调编写异步递归walkdir函数

  28. 28

    如何使用异步函数异步侦听 Firestore 中的值?

  29. 29

    如何在异步函数中使用“ yield”?

热门标签

归档