首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用过时的v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)更新代码?

使用过时的v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)更新代码?
EN

Stack Overflow用户
提问于 2020-11-23 09:56:05
回答 2查看 407关注 0票数 0

我正在更新一个NodeJS package,由于NodeJS 14中的一个损坏。这个库使用了C++代码。在NodeJS 12中,相同的代码显示为弃用警告:

warning: ‘v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)’ is deprecated: Use maybe version

有问题的代码是:

代码语言:javascript
复制
v8::Local<v8::Object> options = v8::Local<v8::Object>::Cast(info[0]);
v8::Local<v8::Value> debug = options->Get(Nan::New<v8::String>("debug").ToLocalChecked());

if (true) {
    v8::Local<v8::Value> leds = options->Get(Nan::New<v8::String>("leds").ToLocalChecked());

    if (!leds->IsUndefined())
        ws2811.channel[0].count = Nan::To<int>(leds).FromMaybe(ws2811.channel[0].count);
    else
        return Nan::ThrowTypeError("configure(): leds must be defined");
}

我确实尝试了下面的代码,虽然它确实编译了,但运行时表明这可能是错误的,因为我得到了在此代码更改之前不存在的失败:

代码语言:javascript
复制
v8::Local<v8::Object> options = v8::Local<v8::Object>::Cast(info[0]);
Nan::MaybeLocal<v8::Value> debug = Nan::Get(options, Nan::New<v8::String>("debug").ToLocalChecked());

if (true) {
    Nan::MaybeLocal<v8::Value> maybe_leds = Nan::Get(options, Nan::New<v8::String>("leds").ToLocalChecked());
    v8::Local<v8::Value> leds;

    if (!maybe_leds.IsEmpty() && maybe_leds.ToLocal(&leds))
        ws2811.channel[0].count = Nan::To<int>(leds).FromMaybe(ws2811.channel[0].count);
    else
        return Nan::ThrowTypeError("configure(): leds must be defined");
}

我对C++相当生疏,对V8也很陌生,在这种情况下,我有点困惑于Get方法的正确替代品是什么。我确实认为我理解的是我们需要使用MaybeLocal而不是Local。进行搜索会发现许多其他人也有类似的问题,但没有一个我可以用作解决方案。

顺便说一句,这个项目确实依赖于nan

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-11-23 21:12:33

关键的见解是,大多数涉及JavaScript的操作都可以抛出异常,而不是返回值。MaybeLocal约定明确了这一点:MaybeLocal要么是Local (如果函数/操作返回一个值),要么是empty (如果有异常)。如果您有一个v8::TryCatchNan::TryCatch,它将在后一种情况下捕获异常。

有几种嵌入代码来处理MaybeLocals的方法;最优雅的是bool-returning .ToLocal(...)方法。它等同于检查.IsEmpty(),所以你不需要同时做这两件事。

所以这会给你带来:

代码语言:javascript
复制
Nan::TryCatch try_catch;
v8::Local<v8::String> leds_string = Nan::New<v8::String>("leds").ToLocalChecked();
Nan::MaybeLocal<v8::Value> maybe_leds = Nan::Get(options, leds_string);

v8::Local<v8::Value> leds;
if (!maybe_leds.ToLocal(&leds)) {
  // An exception was thrown while reading `options["leds"]`.
  // This is the same as `maybe_leds.IsEmpty() == true`.
  // It is also the same as `try_catch.HasCaught() == true`.
  return try_catch.ReThrow();
}
// Now follows your original code.
if (leds->IsUndefined()) {
  // The `options` object didn't have a `leds` property, or it was undefined.
  return Nan::ThrowTypeError("configure(): leds must be defined");
}

// Success case: all good.
ws2811.channel[0].count = Nan::To<int>(leds).FromMaybe(ws2811.channel[0].count);

请参阅https://github.com/nodejs/nan/blob/master/doc/maybe_types.md上的文档。

票数 0
EN

Stack Overflow用户

发布于 2020-11-23 12:40:00

通过更多的挖掘,这似乎是正确的方法。这基本上是根据我在网上找到的Nan文档和代码片段拼凑而成的:

代码语言:javascript
复制
v8::Local<v8::Object> options = v8::Local<v8::Object>::Cast(info[0]);
v8::MaybeLocal<v8::Value> debug = Nan::Get(options, Nan::New<v8::String>("debug").ToLocalChecked());

if (Nan::Has(options, Nan::New<v8::String>("leds").ToLocalChecked()).ToChecked()) {
    Nan::MaybeLocal<v8::Value> maybe_leds = Nan::Get(options, Nan::New<v8::String>("leds").ToLocalChecked());
    v8::Local<v8::Value> leds;

    if (maybe_leds.ToLocal(&leds))
        ws2811.channel[0].count = Nan::To<int>(leds).FromMaybe(ws2811.channel[0].count);
    else
        return Nan::ThrowTypeError("configure(): leds must be defined");
}

看起来Nan::Has检查很重要,否则代码看起来行为不正确。

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

https://stackoverflow.com/questions/64961662

复制
相关文章

相似问题

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