Javascript生成器函数 - 用C ++编写 [英] Javascript generator function -- written in C++
问题描述
使用V8 C ++ API,如何实现生成器接口以在Javascript中使用?我想创建一个对象,可以用作 for-of
循环的迭代器。
Using the V8 C++ API, how can I implement the generator interface for use in Javascript? I'd like to create an object that can be used as the iterator for a for-of
loop.
推荐答案
看起来第一件事就是检查 Symbol.iterator
的属性查找:
Looks like the first thing that's necessary is to check for a property lookup for Symbol.iterator
:
NAN_PROPERTY_GETTER(My_Obj::Getter) {
auto self = Nan::ObjectWrap::Unwrap<My_Obj>(info.This());
if (property->IsSymbol()) {
if (Nan::Equals(property, v8::Symbol::GetIterator(info.GetIsolate())).FromJust()) {
...
使用不带参数的函数进行响应。该函数返回一个对象,其 next
属性设置为另一个函数:
Respond with a function that takes no arguments. The function returns an object with a next
property set to another function:
...
auto iter_template = Nan::New<v8::FunctionTemplate>();
Nan::SetCallHandler(iter_template, [](const Nan::FunctionCallbackInfo<v8::Value> &info) {
auto next_template = Nan::New<v8::FunctionTemplate>();
Nan::SetCallHandler(next_template, My_Obj::next, info.Data());
auto obj = Nan::New<v8::Object>();
Nan::Set(obj, Nan::New<v8::String>("next").ToLocalChecked(),
next_template->GetFunction());
info.GetReturnValue().Set(obj);
}, info.This());
info.GetReturnValue().Set(iter_template->GetFunction());
...
next
函数也不带参数。它在每次调用时按顺序返回迭代值。我正在使用C ++迭代器:
The next
function also takes no arguments. It returns iteration values sequentially on each call. I'm using a C++ iterator for this:
NAN_METHOD(My_Obj::next) {
auto self = Nan::ObjectWrap::Unwrap<My_Obj>(info.Data().As<v8::Object>());
bool done = self->iter == self->contents.end();
auto obj = Nan::New<v8::Object>();
Nan::Set(obj, Nan::New<v8::String>("done").ToLocalChecked(),
Nan::New<v8::Boolean>(done));
if (!done) {
Nan::Set(obj, Nan::New<v8::String>("value").ToLocalChecked(),
Nan::New<v8::String>(self->iter->first.c_str()).ToLocalChecked());
}
self->iter++;
info.GetReturnValue().Set(obj);
}
我将状态保存在包装对象本身中。这使得这个生成器不可重入。对于读/写对象来说这可能是好的,因为可能需要另外一种状态保持方法。
I'm keeping state in the wrapped object itself. That makes this generator non-reentrant. That's probably fine for a read/write object, for something read-only another state-keeping approach is probably warranted.
示例对象的完整代码可用。
这篇关于Javascript生成器函数 - 用C ++编写的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!