我如何知道Stream(Node.js,MongoDB)何时准备好进行更改?

时间:2019-06-21 08:43:47

标签: javascript node.js mongodb

我想确保Stream可以进行更改,然后才能将数据发送到客户端。我的代码:

// Get the Stream (MongoDB collection)
let stream = collection.watch()
// Generate identifier to send it to the client
const uuid = uuid()
// Listen for changes
stream
  .on('change', () => {
    // Send something to WebSocket client
    webSocket.emit('identifier', uuid)
  })

// Mutate data base collection to kick off the "change" event
await collection.updateOne()

我遇到的问题是webSocket.emit。我怎么知道Stream是否已经准备好接收事件?碰巧没有发生change事件,因此从未调用webSocket.emit

TL; DR

基本上,我需要向客户端发送一些内容,但需要确保Stream可以在此之前接收事件。

1 个答案:

答案 0 :(得分:1)

这看起来像一个竞争条件,其中您的更新查询在changeStream聚合管道到达服务器之前执行。基本上,您需要等待流游标设置之后才能触发更改。

我找不到任何“光标准备就绪”事件,因此,作为一种变通办法,您可以检查其ID。它是由服务器分配的,因此当它在客户端上可用时,可以保证将捕获所有连续的数据更改。

类似的事情应该可以完成:

async function streamReady(stream) {
    return new Promise(ok => {
        const i = setInterval(() => {
            if (stream.cursor.cursorState.cursorId) {
                clearInterval(i);
                return ok()
            }
        }, 1)
    });
}

然后在您的代码中:

// Get the Stream (MongoDB collection)
let stream = collection.watch()
// Generate identifier to send it to the client
const uuid = uuid()
// Listen for changes
stream
  .on('change', () => {
    // Send something to WebSocket client
    webSocket.emit('identifier', uuid)
  })

await streamReady(stream);    

// Mutate data base collection to kick off the "change" event
await collection.updateOne()

免责声明:

上面的streamReady函数依赖于cursorState。这是一个内部字段,即使在驱动程序的修补程序版本更新中也可以在不通知的情况下进行更改。