Intereting Posts

asynchronous构buildV8string数组

我正在构build一个节点模块来与libapt进行交互,以便列出和控制已安装的软件包。 我通过实现一个函数来获取每个已安装软件包的名称,从而开始简单。 我已经撞墙了。

我目前有这样的代码:

 #include <apt-pkg/init.h> #include <apt-pkg/cachefile.h> #include <apt-pkg/pkgcache.h> #include <node.h> #include <v8.h> using namespace v8; typedef struct AsyncData { Persistent<Function> callback; // callback function Handle<Array> packageList; // array of package names } AsyncData; void AsyncWork(uv_work_t *req) { AsyncData *asyncData = (AsyncData *)req->data; asyncData->packageList = Array::New(); size_t i = 0; for (pkgCache::PkgIterator package = cache->PkgBegin(); !package.end(); package++) { if(package->CurrentVer == 0) continue; asyncData->packageList->Set(i++, String::New(package.Name())); } } void AsyncAfter(uv_work_t *req) { HandleScope scope; AsyncData *asyncData = (AsyncData *)req->data; Handle<Value> argv[] = { Null(), asyncData->packageList }; TryCatch try_catch; asyncData->callback->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) node::FatalException(try_catch); asyncData->callback.Dispose(); delete asyncData; delete req; } Handle<Value> InstalledPackages(const Arguments& args) { HandleScope scope; uv_work_t *req = new uv_work_t; AsyncData *asyncData = new AsyncData; req->data = asyncData; asyncData->callback = Persistent<Function>::New(Local<Function>::Cast(args[1])); uv_queue_work( uv_default_loop(), req, // work token AsyncWork, // work function (uv_after_work_cb)AsyncAfter // function to run when complete ); return scope.Close(Undefined()); } void Initialize(Handle<Object> exports) { pkgInitConfig(*_config); pkgInitSystem(*_config, _system); // function hello(); exports->Set(String::NewSymbol("getInstalledPackages"), FunctionTemplate::New(InstalledPackages)->GetFunction()); } NODE_MODULE(apt, Initialize) 

主要的问题是你不能在主事件循环以外的线程中使用任何V8对象。 这意味着我在上面的代码中得到了段错误。 所以我修改了我的代码如下:

 #include <apt-pkg/init.h> #include <apt-pkg/cachefile.h> #include <apt-pkg/pkgcache.h> #include <node.h> #include <v8.h> using namespace std; using namespace v8; typedef struct AsyncData { Persistent<Function> callback; // callback function vector<string> packageList; // array of package names } AsyncData; void AsyncWork(uv_work_t *req) { AsyncData *asyncData = (AsyncData *)req->data; pkgCacheFile cache_file; pkgCache* cache = cache_file.GetPkgCache(); for (pkgCache::PkgIterator package = cache->PkgBegin(); !package.end(); package++) { // If the current package has Version of 0, its no installed if(package->CurrentVer == 0) continue; asyncData->packageList.push_back(package.Name()); } } void AsyncAfter(uv_work_t *req) { HandleScope scope; AsyncData *asyncData = (AsyncData *)req->data; Handle<Array> packageArray = Array::New(asyncData->packageList.size()); for(size_t i = 0; i < asyncData->packageList.size(); i++) { packageArray->Set(i, String::New(asyncData->packageList[i].c_str())); } Handle<Value> argv[] = { Null(), packageArray }; TryCatch try_catch; asyncData->callback->Call(Context::GetCurrent()->Global(), 2, argv); if (try_catch.HasCaught()) node::FatalException(try_catch); asyncData->callback.Dispose(); delete asyncData; delete req; } Handle<Value> InstalledPackages(const Arguments& args) { HandleScope scope; uv_work_t *req = new uv_work_t; AsyncData *asyncData = new AsyncData; req->data = asyncData; asyncData->callback = Persistent<Function>::New(Local<Function>::Cast(args[0])); uv_queue_work( uv_default_loop(), req, // work token AsyncWork, // work function (uv_after_work_cb)AsyncAfter // function to run when complete ); return scope.Close(Undefined()); } void Initialize(Handle<Object> exports) { pkgInitConfig(*_config); pkgInitSystem(*_config, _system); // function hello(); exports->Set(String::NewSymbol("getInstalledPackages"), FunctionTemplate::New(InstalledPackages)->GetFunction()); } NODE_MODULE(apt, Initialize) 

这段代码现在可以工作,但是我现在正在循环查看string列表,并在主事件循环中创build新的V8string。 我可能已经完成了所有的同步开始。 由于包列表可能是30000string长,我不想在JavaScript事件循环中做到这一点。 我怎样才能asynchronous创build大量的string数组?

Solutions Collecting From Web of "asynchronous构buildV8string数组"