簡體   English   中英

Javascript生成器函數 - 用C ++編寫

[英]Javascript generator function — written in C++

使用V8 C ++ API,如何實現生成器接口以在Javascript中使用? 我想創建一個可以用作for-of循環的迭代器的對象。

看起來第一件事就是檢查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);
}

我將狀態保存在被包裹的對象中。 這使得這個生成器不可重入。 對於讀/寫對象來說這可能是好的,因為對於只讀的另一種狀態保持方法可能是必要的。

可以使用示例對象完整代碼

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM