【问题标题】:How to code an async stream generator in javascript without a buffer如何在没有缓冲区的 javascript 中编写异步流生成器
【发布时间】: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


【解决方案1】:

我有同样的问题,可以在没有缓冲区和生成器的情况下简化解决方案。

我终于在Node-Media-Server 项目async branch 中为我找到了更好的异步功能解决方案。

在 v1.2.7 中是 generator function

我测试了我使用提供的异步和生成器功能解决方案构建的 RTSP 服务器的性能,并得到了相同的结果。我记得每个 cpu 核心有几个 Gbits/sec 和 1000 个并发客户端。

【讨论】:

    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2013-01-17
    • 2017-05-12
    • 2015-03-17
    相关资源
    最近更新 更多