Я использую AsyncWorker
для запуска асинхронной задачи. Проблема в том, что у меня есть множество задач, которые нужно выполнить, одну за другой, и порядок важен. Чтобы поддерживать порядок, я использую технику очередей, чтобы убедиться, что AsyncWorker
объекты созданы в правильном порядке, только после завершения каждой задачи. Я сохраняю Обратный вызов в vector<Function>
и передаю его в AsyncWorker
, но получаю следующую ошибку:
# Fatal error in v8::HandleScope::CreateHandle()
# Cannot create a handle without a HandleScope
Есть ли какой-то другой способ сделать это? Я также попытался использовать Napi::Persistent
, но я не могу передать переменную Napi::FunctionReference
в AsyncWorker
Функции вызывающей стороны:
Napi::Value BlockChainWrapper::genesis(const Napi::CallbackInfo& info) {
std::lock_guard<std::mutex> guard_ready_queue(ready_queue_mutex);
this->ready_queue_callback.push_back(info[1].As<Napi::Function>());
this->ready_queue_data.push_back(info[0].As<Napi::Object>());
this->ready_queue_func.push_back(BlockChainWrapperTypes::_genesis_ready);
this->ready_queue_env.push_back(info.Env());
return info.Env().Undefined();
}
void BlockChainWrapper::genesis_ready() {
AsyncBlockChainFunctions* asyncWorker = new AsyncBlockChainFunctions(this->ready_queue_callback.front(), 0, blockchain_obj, this->ready_queue_data.front());
asyncWorker->Queue();
}
Конструктор AsyncWorker:
AsyncBlockChainFunctions::AsyncBlockChainFunctions(Napi::Function& callback, int mode, std::shared_ptr<BlockChain> _blockchain, Napi::Object& resource) : AsyncWorker(callback), mode(mode) {};
РЕДАКТИРОВАТЬ 1 Я реализовал PromiseWorker, но все еще сталкивался с этими ошибками: BlockChainWrapper наследует ObjectWrap.
Napi::Object BlockChainWrapper::Init(Napi::Env env, Napi::Object exports) {
Napi::HandleScope scope(env);
Napi::Function func = DefineClass(env, "BlockChainWrapper", {
InstanceMethod("genesis", &BlockChainWrapper::genesis)
});
constructor = Napi::Persistent(func);
constructor.SuppressDestruct();
exports.Set("BlockChainWrapper", func);
return exports;
}
# Fatal error in HandleScope::HandleScope
# Entering the V8 API without proper locking in place
Модифицированный конструктор AsyncWorker, функция класса и разрешения:
class AsyncBlockChainFunctions : public PromiseWorker
AsyncBlockChainFunctions(Napi::Promise::Deferred const &d, std::shared_ptr<BlockChain> _blockchain, int mode, Napi::Object& resource) : PromiseWorker(d), mode(mode) {}
void Resolve(Napi::Promise::Deferred const &deferred) {
deferred.Resolve(Napi::String::New(deferred.Env(), this->block_as_json_string));
};
Функция вызывающего абонента:
Napi::Value BlockChainWrapper::genesis(const Napi::CallbackInfo& info) {
std::lock_guard<std::mutex> guard_ready_queue(ready_queue_mutex);
this->ready_queue_data.push_back(info[0].As<Napi::Object>());
this->ready_queue_func.push_back(BlockChainWrapperTypes::_genesis_ready);
this->ready_queue_env.push_back(info.Env());
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(info.Env());
std::cout << "genesis" << std::endl;
return deferred.Promise();
}
Genesis готов вызывается из другого потока управления очередями
void BlockChainWrapper::genesis_ready() {
Napi::Env env = ready_queue_env.front();
Napi::Promise::Deferred deferred = Napi::Promise::Deferred::New(env);
Napi::Object input_obj = this->ready_queue_data.front().As<Napi::Object>();
auto *x = new AsyncBlockChainFunctions(std::ref(deferred), this->blockchain_obj, 0, input_obj);
x->Queue();
}