首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用节点-addon-api实现节点-nan回调

如何使用节点-addon-api实现节点-nan回调
EN

Stack Overflow用户
提问于 2020-01-23 00:22:56
回答 1查看 502关注 0票数 2

到目前为止,我只实现了同步节点- addon方法,即JavaScript函数进行调用,工作完成,addon返回。当涉及到v8、libuv和节点的内部工作时,我在知识方面有很大的差距,所以请纠正任何明显的误解。

目标是在从JavaScript调用C++垃圾回收回调时调用v8回调。我最初只是从JavaScript垃圾回收回调中调用了v8回调,但经过几次调用,最终得到了一个segv。在从JavaScript回调调用时,只调用v8似乎就有一些问题(v8文档--回调不应该分配对象)。所以我环顾四周,发现了一个基于南的例子,它使用libuv和南的AsyncResource进行回调。以下方法使用node-nan工作

代码语言:javascript
复制
NAN_GC_CALLBACK(afterGC) {
    uint64_t et = uv_hrtime() - gcStartTime;

    // other bookkeeping for GCData_t raw.

    if (doCallbacks) {
        uv_async_t* async = new uv_async_t;
        GCData_t* data = new GCData_t;

        *data = raw;
        data->gcTime = et;

        async->data = data;

        uv_async_init(uv_default_loop(), async, asyncCB);
        uv_async_send(async);
    }
}

class GCResponseResource : public Nan::AsyncResource {
 public:
    GCResponseResource(Local<Function> callback_)
        : Nan::AsyncResource("nan:gcstats.DeferredCallback") {
    callback.Reset(callback_);
    }

    ~GCResponseResource() {
        callback.Reset();
    }

    Nan::Persistent<Function> callback;
};

static GCResponseResource* asyncResource;

static void closeCB(uv_handle_t *handle) {
    delete handle;
}

static void asyncCB(uv_async_t *handle) {
    Nan::HandleScope scope;
    GCData_t* data = static_cast<GCData_t*>(handle->data);

    Local<Object> obj = Nan::New<Object>();

    Nan::Set(obj, Nan::New("gcCount").ToLocalChecked(),
        Nan::New<Number>((data->gcCount));
    Nan::Set(obj, Nan::New("gcTime").ToLocalChecked(),
        Nan::New<Number>(data->gcTime));

    Local<Object> counts = Nan::New<v8::Object>();
    for (int i = 0; i < maxTypeCount; i++) {
        if (data->typeCounts[i] != 0) {
            Nan::Set(counts, i, Nan::New<Number>(data->typeCounts[i]));
        }
    }
    Nan::Set(obj, Nan::New("gcTypeCounts").ToLocalChecked(), counts);

    Local<Value> arguments[] = {obj};
    Local<Function> callback = Nan::New(asyncResource->callback);
    v8::Local<v8::Object> target = Nan::New<v8::Object>();
    asyncResource->runInAsyncScope(target, callback, 1, arguments);
    delete data;
    uv_close((uv_handle_t*) handle, closeCB);
}

我的问题是如何使用节点-addon而不是nan来完成这个任务?

我不清楚节点-addon等同于uv_async_inituv_async_send等是什么。这部分是因为我不清楚需要什么底层N-API (而不是node-addon-api)函数。

我一直找不到这样的例子。回调示例是完全同步的。异步pi示例使用一个工作线程来执行一个任务,但与使用uv原语的基于nan的代码中的方法相比,这似乎是过分的。

EN

回答 1

Stack Overflow用户

发布于 2022-01-03 13:19:05

您的示例实际上不是异步的,因为GC回调在主线程中运行。但是,当由于GC而停止JS世界时,这并不意味着它以允许回调的方式停止--因为GC可以在函数的中间停止它。

您需要一个ThreadSafeFunction来完成这个任务。看看这里有一个例子:function.md

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59870076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档