V8 使用已弃用的 v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>) 更新代码?
V8 updating code using deprecated v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)?
由于 NodeJS 14 的损坏,我正在更新 NodeJS package。该库使用 C++ 代码。在 NodeJS 12 中,相同的代码显示为弃用警告:
warning: ‘v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)’ is deprecated: Use maybe version
有问题的代码是:
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");
}
我确实尝试了以下方法,虽然它确实编译了,但运行时提示这可能是错误的,因为我遇到了在此代码更改之前不存在的失败:
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。
经过更多挖掘,这似乎是正确的方法。这基本上是根据我在网上找到的 Nan 文档和片段拼凑而成的:
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
检查很重要,否则代码似乎无法正常运行。
关键的见解是涉及 JavaScript 的大多数操作都可以抛出异常而不是返回值。 MaybeLocal
约定明确说明了这一点:MaybeLocal
要么是 Local(如果 function/operation 返回了一个值),要么是空的(如果有异常)。如果你有 v8::TryCatch
或 Nan::TryCatch
,它会捕获后一种情况下的异常。
嵌入代码处理MaybeLocals的方式有多种;最优雅的是 bool
-返回 .ToLocal(...)
方法。相当于检查.IsEmpty()
,所以你不需要两者都做。
所以这会给你:
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 处的文档。
由于 NodeJS 14 的损坏,我正在更新 NodeJS package。该库使用 C++ 代码。在 NodeJS 12 中,相同的代码显示为弃用警告:
warning: ‘v8::Local<v8::Value> v8::Object::Get(v8::Local<v8::Value>)’ is deprecated: Use maybe version
有问题的代码是:
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");
}
我确实尝试了以下方法,虽然它确实编译了,但运行时提示这可能是错误的,因为我遇到了在此代码更改之前不存在的失败:
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。
经过更多挖掘,这似乎是正确的方法。这基本上是根据我在网上找到的 Nan 文档和片段拼凑而成的:
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
检查很重要,否则代码似乎无法正常运行。
关键的见解是涉及 JavaScript 的大多数操作都可以抛出异常而不是返回值。 MaybeLocal
约定明确说明了这一点:MaybeLocal
要么是 Local(如果 function/operation 返回了一个值),要么是空的(如果有异常)。如果你有 v8::TryCatch
或 Nan::TryCatch
,它会捕获后一种情况下的异常。
嵌入代码处理MaybeLocals的方式有多种;最优雅的是 bool
-返回 .ToLocal(...)
方法。相当于检查.IsEmpty()
,所以你不需要两者都做。
所以这会给你:
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 处的文档。