【发布时间】:2019-12-02 01:16:41
【问题描述】:
我们希望将来自生成器的流数据事件消耗到转换/转换管道中。
生成器的一种形式如下
var generator = async function* () {
var value
while(true){
value = await new Promise((resolve)=>{
value = ... // some functionality
resolve(value)
})
yield value
}
}
假设有一个正在产生值的数据流。有一个工厂函数可以使用处理函数
async function makeStream(handler) {
...
}
handle 函数将提供一个表示从流中生成的值的有效负载。
var handler = function(payload){
}
对于流,我们需要提供一个回调。对于生成器,我们需要在调用处理程序时解析承诺。我们希望能够编写如下代码:
function makeCallbackGenerator() {
var handler
var generator = async function*() {
while(true){
var value = await new Promise((resolve)=>{
handler = function(payload){
resolve(payload)
}
})
yield value
}
}
return {
handler,
generator
}
}
这是一个产生的工厂函数
- 发电机
- 回调
需要将回调传递到流中。生成器需要传入转换管道。
但是这个声明是不对的。我们不想在 promise 的每次迭代中定义函数,而是希望在每次迭代时使用函数来解析 promise。
根本问题是如何在promise中定义回调,以便流可以耦合到生成器。
一种解决方法是在流和生成器之间使用缓冲区。
function makeCallbackGenerator() {
var buffer = []
var handler = function(payload){
buffer.push(payload)
return 1//consumed
}
var start = async function* () {
while(true){
if(buffer.length>0){
var next = buffer.pop()
debug("Generator yield")
yield next
}else {
await new Promise((resolve)=>{
setTimeout(()=>resolve(),1000)
})
}
}
}
return {
handler, start
}
}
有没有更简单的方法可以在没有缓冲区的情况下实现这一点?
【问题讨论】:
-
感谢您的提问,这是异步流生成器非常漂亮的解决方案。但我不明白你为什么希望这更简单。它已经是一个复杂问题的简单解决方案。我试图了解您希望在这里实现什么。再次,好问题!
-
消除缓冲区会很好,因为它可能是内存泄漏并且会使代码更加复杂。从根本上说,我只想将传入的回调方法与生成器链接......这样它就可以提供一个转导管道 (npmjs.com/package/funprog)
-
您可以使用互斥锁并锁定缓冲区以消除任何竞争条件,也在您提供的链接中,类似于您的示例代码;它使用 MongoDB,就像一个缓冲区。那么为什么不使用缓冲区呢?
标签: javascript async-await generator event-stream-processing