#c #node.js #v8
#c #node.js #v8
Вопрос:
Я нахожусь в процессе обновления пакета NodeJS из-за поломки в NodeJS 14. Эта библиотека использует код 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() amp;amp; maybe_leds.ToLocal(amp;leds))
ws2811.channel[0].count = Nan::To<int>(leds).FromMaybe(ws2811.channel[0].count);
else
return Nan::ThrowTypeError("configure(): leds must be defined");
}
Будучи довольно знакомым с C и новичком в версии 8, я немного сбит с толку относительно того, какая правильная замена для этого Get
метода в данном контексте. Я думаю, я понимаю, что нам нужно использовать MaybeLocal
вместо Local
. При выполнении поиска появляется много других людей с похожими проблемами, но ничего, что я мог бы использовать в качестве решения.
Кстати, этот проект зависит от nan.
Ответ №1:
Ключевым моментом является то, что большинство операций, связанных с JavaScript, могут генерировать исключение вместо возврата значения. MaybeLocal
Соглашение делает это явным: a MaybeLocal
является либо локальным (если функция / операция вернула значение), либо пустым (если было исключение). Если у вас есть v8::TryCatch
или Nan::TryCatch
, он поймает исключение в последнем случае.
Существует несколько способов встраивания кода для работы с MaybeLocals; наиболее элегантным является метод bool
-returning .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(amp;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 .
Ответ №2:
Если еще немного покопаться, это кажется правильным подходом. По сути, это составлено на основе документов 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(amp;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
, проверка важна, иначе код, похоже, ведет себя некорректно.
Комментарии:
1. Нет,
Nan::Has
это не важно, он просто описывает один конкретный случай сбоя, который вы можете более элегантно проверить другими способами. Подробности см. в моем ответе.