node.js - Node.js 流可以做成协程吗?

标签 node.js generator coroutine

有没有办法让 Node.js 流成为协程。

例子 斐波那契数字流。

fibonacci.on('data', cb);
//The callback (cb) is like
function cb(data)
{
    //something done with data here ...
}

期待

function* fibonacciGenerator()
{
    fibonacci.on('data', cb);
    //Don't know what has to be done further... 
};

var fibGen = fibonacciGenerator();
fibGen.next().value(cb);
fibGen.next().value(cb);
fibGen.next().value(cb);
.
.
.

从生成器中获取所需的数字。这里斐波那契数列只是一个例子,实际上流可以是任何文件,mongodb查询结果等。

也许是这样的

  1. 将“stream.on”函数作为生成器。
  2. 将 yield 放在回调函数中。
  3. 获取生成器对象。
  4. 调用 next 并获取流中的下一个值。

是否至少有可能,如果是,如何,如果不可能,为什么?也许是个愚蠢的问题:)

最佳答案

如果您不想使用转译器(例如 Babel)或等到 async/await 将其转换为 Node.js,您可以自己使用生成器和 promise 。

缺点是您的代码必须位于生成器中。



首先,您可以制作一个接收流并返回一个函数的助手,该函数在被调用时返回对流的下一个“事件”的 promise (例如 data)。

function streamToPromises(stream) {
  return function() {
    if (stream.isPaused()) {
      stream.resume();
    }

    return new Promise(function(resolve) {
      stream.once('data', function() {
        resolve.apply(stream, arguments);
        stream.pause();
      });
    });
  }
}

它会在您不使用它时暂停流,并在您向它询问下一个值时恢复它。


接下来,您有一个助手,它接收一个生成器作为参数,每次它产生一个 promise 时,它都会解析它并将其结果传递回生成器。

function run(fn) {
  var gen = fn();
  var promise = gen.next().value;

  var tick = function() {
    promise.then(function() {
      promise = gen.next.apply(gen, arguments).value;
    }).catch(function(err) {
      // TODO: Handle error.
    }).then(function() {
      tick();
    });
  }

  tick();
}

最后,您将在生成器中执行您自己的逻辑,并使用 run 帮助程序运行它,如下所示:

run(function*() {
  var nextFib = streamToPromises(fibonacci);

  var n;

  n = yield nextFib();
  console.log(n);

  n = yield nextFib();
  console.log(n);
});
  • 您自己的生成器将产生 promise ,暂停其执行并将控制权传递给 run 函数。
  • run 函数将解决 promise 并将其值传递回您自己的生成器。

这就是它的要点。您需要修改 streamToPromises 以检查其他事件(例如 enderror)。

关于node.js - Node.js 流可以做成协程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39426849/

相关文章:

kotlin GlobalScope,runBlocking 在 kotlin.coroutines 中不可用。*

javascript - JavaScript中的数据竞赛?

node.js - 如果在 NodeJs 中,则有一个衬垫

javascript - 从 app.js(node) 发送和检索数据到 javascript(main.js)

node.js - 将 WebStorm 连接到远程 node.js 调试 session

javascript - javascript es6 迭代器惰性求值在内存中如何工作?

JavaScript 生成器 - 如何在使用 .next() 调用时跳过 yield?

python - Matplotlib 绘图生成器

python - 使用 asyncio 的程序结构

c++ - 协程 TS 2017 的实现示例