N-API中的Promise功能的使用

大雄45發表於2021-06-19
導讀 本文介紹N-API中的Promise功能的使用。Promise相關的API一共有四個。在回撥裡,透過napi_resolve_deferred或napi_reject_deferred修改Promise(deferred)的狀態,這時候,js層的回撥就會被執行。以上就是N-API中關於Promise的使用。

N-API中的Promise功能的使用N-API中的Promise功能的使用

本文介紹N-API中的Promise功能的使用。Promise相關的API一共有四個。

napi_create_promise // 建立一個Promise,類似new Promise 
napi_resolve_deferred // resolve一個Promise 
napi_reject_deferred // reject一個Promise 
napi_is_promise // 判斷變數是否是一個Promise

我們首先看一下napi_is_promise。測試程式碼如下:

const { isPromise } = require('./build/Release/test.node'); 
console.log('is Promise', isPromise(1), isPromise(Promise.resolve()));

接著看看N-API的實現。

static napi_value isPromise(napi_env env, napi_callback_info info) { 
  napi_value result; 
  size_t argc = 1; 
  napi_value argv[1]; 
  bool is_promise; 
 
  napi_get_cb_info(env, info, &argc, argv, NULL, NULL); 
  napi_is_promise(env, argv[0], &is_promise); 
  napi_get_boolean(env, is_promise, &result); 
 
  return result; 
} 
 
napi_value Init(napi_env env, napi_value exports) { 
  napi_value func2; 
  napi_create_function(env, 
                      NULL, 
                      NAPI_AUTO_LENGTH, 
                      isPromise, 
                      NULL, 
                      &func2); 
  napi_set_named_property(env, exports, "isPromise", func2); 
 
  return exports; 
}

我們看到實現比較簡單,只是封裝了N-API的API。我們繼續看Promise的真正使用。測試程式碼如下

const { getPromise, isPromise } = require('./build/Release/test.node'); 
getPromise() 
    .then( 
        (result) => { 
            console.log('resolve', result) 
        },  
        (result) => { 
            console.log('reject',result) 
        } 
    );

接著看N-API的實現。

struct info{ 
  napi_async_work worker; 
  napi_deferred deferred; 
  int sum; 
}; 
 
static napi_value getPromise(napi_env env, napi_callback_info info) { 
  napi_value promise; 
  napi_value resource_name; 
  struct info data = {nullptr, nullptr, 0}; 
  struct info * ptr = &data; 
  napi_create_promise(env, &ptr->deferred, &promise); 
  napi_create_string_utf8(env,"test", NAPI_AUTO_LENGTH, &resource_name); 
  napi_create_async_work(env, nullptr, resource_name, work, done, (void *)ptr, &ptr->worker); 
  napi_queue_async_work(env, ptr->worker); 
 
  return promise; 
} 
 
napi_value Init(napi_env env, napi_value exports) { 
  napi_value func; 
  napi_create_function(env, 
                      NULL, 
                      NAPI_AUTO_LENGTH, 
                      getPromise, 
                      NULL, 
                      &func); 
  napi_set_named_property(env, exports, "getPromise", func); 
 
  return exports; 
}

首先透過napi_create_promise建立一個Promise。然後返回給js層,但是這個Promise是未決議的,這裡我們透過給Libuv執行緒池實現一個非同步的操作,然後在回撥裡resolve這個Promise。napi_create_promise API會生成兩個物件,一個Promise(返回給js),一個是deferred,我們修改Promise狀態的時候,是透過操作deferred變數,所以我們首先儲存了該變數的值,然後在非同步回撥裡修改它的狀態。我們看看執行緒池裡執行的程式碼。

void work(napi_env env, void* data) { 
  struct info *arg = (struct info *)data; 
  int sum = 0; 
  for (int i = 0; i < 1000; i++) { 
    sum += i; 
  } 
  arg->sum = sum; 
}

我們在子執行緒裡做一個計算,然後把結果儲存到info裡,接著在回撥裡做進一步處理。

void done(napi_env env, napi_status status, void* data) {  
  struct info *arg = (struct info *)data; 
  napi_value ret; 
  if (true) { 
    napi_create_int32(env, arg->sum, &ret); 
    napi_resolve_deferred(env, arg->deferred, ret); 
  } else { 
    napi_create_int32(env, 0, &ret); 
    napi_reject_deferred(env, arg->deferred, ret); 
  } 
  napi_delete_async_work(env, arg->worker); 
  arg->deferred = nullptr; 
}

在回撥裡,透過napi_resolve_deferred或napi_reject_deferred修改Promise(deferred)的狀態,這時候,js層的回撥就會被執行。以上就是N-API中關於Promise的使用。

原文來自:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69955379/viewspace-2777432/,如需轉載,請註明出處,否則將追究法律責任。

相關文章