N-API之Promise篇
本文介紹N-API中的Promise功能的使用。Promise相關(guān)的API一共有四個。
- napi_create_promise // 創(chuàng)建一個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的實現(xiàn)。
- 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;
- }
我們看到實現(xiàn)比較簡單,只是封裝了N-API的API。我們繼續(xù)看Promise的真正使用。測試代碼如下
- const { getPromise, isPromise } = require('./build/Release/test.node');
- getPromise()
- .then(
- (result) => {
- console.log('resolve', result)
- },
- (result) => {
- console.log('reject',result)
- }
- );
接著看N-API的實現(xiàn)。
- 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創(chuàng)建一個Promise。然后返回給js層,但是這個Promise是未決議的,這里我們通過給Libuv線程池實現(xiàn)一個異步的操作,然后在回調(diào)里resolve這個Promise。napi_create_promise API會生成兩個對象,一個Promise(返回給js),一個是deferred,我們修改Promise狀態(tài)的時候,是通過操作deferred變量,所以我們首先保存了該變量的值,然后在異步回調(diào)里修改它的狀態(tài)。我們看看線程池里執(zhí)行的代碼。
- 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;
- }
我們在子線程里做一個計算,然后把結(jié)果保存到info里,接著在回調(diào)里做進(jìn)一步處理。
- 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;
- }
在回調(diào)里,通過napi_resolve_deferred或napi_reject_deferred修改Promise(deferred)的狀態(tài),這時候,js層的回調(diào)就會被執(zhí)行。以上就是N-API中關(guān)于Promise的使用。