【问题标题】:Javascript generator function -- written in C++Javascript 生成器函数——用 C++ 编写
【发布时间】:2016-08-02 02:12:56
【问题描述】:

使用 V8 C++ API,如何实现生成器接口以在 Javascript 中使用?我想创建一个可用作for-of 循环的迭代器的对象。

【问题讨论】:

  • 嗯,祝你遇到这种“规范问题”

标签: javascript c++ generator v8


【解决方案1】:

看起来首先需要检查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 属性设置为另一个函数:

      ...
      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++ 迭代器:

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);
}

我将状态保存在被包装的对象本身中。这使得这个生成器不可重入。这对于读/写对象可能没问题,因为只读的东西可能需要另一种状态保持方法。

full code for an example object 可用。

【讨论】:

  • “看起来第一件事是检查 Symbol.iterator 的属性查找” - 有没有办法使用 Node.js 0.12 做到这一点?看起来 V8 3.28.71.19 中的 Symbol 类没有 GetIterator 函数。
猜你喜欢
  • 2020-07-24
  • 1970-01-01
  • 1970-01-01
  • 2015-11-05
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
相关资源
最近更新 更多