有没有办法让 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查询结果等。
也许是这样的
- 将“stream.on”函数作为生成器。
- 将 yield 放在回调函数中。
- 获取生成器对象。
- 调用 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
以检查其他事件(例如 end
或 error
)。
关于node.js - Node.js 流可以做成协程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39426849/