【问题标题】:Turn Generator to JSON JS将生成器转为 JSON JS
【发布时间】:2015-11-05 11:48:31
【问题描述】:

我最近开始研究 JS 和 Node.js。但是我并不完全喜欢编写回调风格的代码,所以我开始为 Node.js 编写一个小框架。我已经完成了它,但现在我正试图让它在节点集群的多核上工作。问题是,我不能将生成器从主服务器发送给工作人员,因为我的框架是基于生成器的,我必须让工作人员运行生成器。我如何将生成器对象转换为 JSON,然后我可以将其发送给我的工作人员或将生成器发送给工作人员的其他方法?我尝试将生成器转换为 JSON,但结果是一个没有 next 或 throw 方法的空对象。

以下是乒乓球的示例:

Thr.setNumCPUs(require("os").CPUS.length-1) 
//not to have one extra because of the master
function ping(times){
    var chan = new Thr.Chan();//create new channel
    Thr.spwn(function* (){//start a new thr, on any of the cpus
       var chan2 = pong(chan);
       for (var i= 0;i < times;i++){
          yield* chan.send("ping, for the "+(i+1)+" timth");
          //wait untill chan is empty, then send a value
          console.log(yield* chan2.rcv());
          //wait until received the value
       }
       chan.close();
       //close the channel so now on can access it
     }  ,[]);
}


function pong(chan){
   var chan2 = new Thr.Chan();
   Thr.spwn(function* (){
       var i = 0;
       while (!chan.closed){
          console.log(yield* chan.rcv());
           yield* chan2.send("pong, for the "+(++i)+" timth");
       }
       chan2.close();
   }  ,[]);
   return chan2;
}
if (cluster.isMaster){
    ping(5);
}

【问题讨论】:

  • 原生 JSON 解析器无法评估 JSON 中的函数,它们无效。
  • 我知道,但是,有没有另一种方法来解析它,或者以不同的方式将结果发送给工作人员。我什至无法将函数 *.next 放到字符串中。
  • 您必须实现自己的 JSON 解析器 (!)
  • 好吧,我可能没有时间这样做,我什至无法将 generator.next 放到一个字符串中。
  • 当您尝试将函数转换为字符串时会发生什么。似乎对我有用。

标签: javascript json node.js generator


【解决方案1】:

JSON 是一种用于序列化数据的格式,而不是可执行函数*。为了将生成器作为 JSON 传递,您实际上需要遍历生成器以生成所有值,将它们存储在类似数组的东西中,然后只需将该数组添加到您要转换为 JSON 的对象中。这可能会消除使用生成器的任何好处,但很容易做到。

我还没有机会使用集群,但我的印象是您可以使用它来简单地将不同的整个节点实例作为集群运行,从而无需手动分叉进程以使用多个处理器.

如果您喜欢使用生成器生成异步代码,有一个名为 co 的库可以做到这一点,您可能刚刚重新发明了它。

【讨论】:

  • 仅适用于非确定性生成器。生成器仍然具有 toString() 并且可以通过 GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor; 将函数作为 json 传递很容易进行重构。添加状态信息也很容易。毕竟生成器只是对象。
  • 很接近,但我有一种不同的方法,而不是结合使用生成器和承诺,我的库有通道,很像 Golang 和 CO 不是多核的,我制作的库非常好用一个核心。
  • 盲人,还有一种方法可以获取生成器函数的代码,我可以在生成器对象创建后转到 JSON,因为库接受生成器对象而不是函数* ,我当然可以更改库,使其接受函数和参数,非常感谢。
  • 在闭包中使用数据的生成器将是不确定的,例如乒乓示例中给出的那些。
【解决方案2】:

实际上,在研究了发电机和在 Blindman 的 cmets 之后,我知道找到了我的问题的答案。我要做的第一件事是为生成器创建构造函数:var GeneratorFunctionConstructor = Object.getPrototypeOf(function*(){}).constructor。然后,当我将工作发送给其中一位工作人员时,我创建了一个 JSON 对象,其中 function* 作为 String 并传递给它的参数。然后我通过获取 function* 的 args 和 function* 主体,使用构造函数创建一个新的 Generator 对象。接下来我调用Generator.apply(this,args) 并开始异步执行它。

【讨论】:

  • 请注意,您将通过它丢失所有闭包变量。多次(在每个集群节点上)实例化您的框架会更明智,并且只在不生成器周围传递数据。
  • 这是个好主意,但你怎么知道哪个生成器传递什么数据。
  • 取决于你的代码和它在做什么。我假设您无论如何都在通过渠道进行进程间通信?然后一种方法可能是在任何地方创建所有生成器,并且只将数据传递给那些应该工作的生成器。或者,如果您关心在哪里实例化什么,并且需要动态执行,那么将所有生成器函数放在一个巨大的对象中,在其中可以通过它们的属性名称来识别它们。
  • 这是否意味着当我创建一个新的生成器时,我会调用已经跨所有线程保存在数据结构中的生成器。
  • 您可以存储生成器本身或在数据结构中创建它们的生成器函数。使用你需要的东西。当您可以发布代码的相关部分时,我们可能会为您提供更好的帮助(作为一个简单的示例,可能是两个集群节点之间的乒乓球)
猜你喜欢
  • 1970-01-01
  • 2020-09-02
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2021-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多