简体   繁体   English

使用highland.js在消费流之前做点什么

[英]Do something before consuming stream, using highland.js

I'm trying to code a writable stream which takes a stream of objects and inputs them into a mongodb database. 我正在尝试编写一个可写流,该流采用对象流并将其输入到mongodb数据库中。 Before consuming the stream of objects, I first need to wait for the db-connection to establish, but I seem to be doing something wrong, because the program never gets to the insertion-part. 在使用对象流之前,我首先需要等待db-connection建立,但是我似乎做错了,因为程序永远不会到达插入部分。

// ./mongowriter.js

let mongo = mongodb.MongoClient,
    connectToDb = _.wrapCallback(mongo.connect);

export default url => _.pipeline(s => {
  return connectToDb(url).flatMap(db => {
    console.log('Connection established!');
    return s.flatMap(x => /* insert x into db */);
  });
});

....

// Usage in other file
import mongowriter from './mongowriter.js';

let objStream = _([/* json objects */]);

objStream.pipe(mongoWriter);

The program just quits without "Connection established!" 该程序只是在没有“建立连接”的情况下退出。 ever being written to the console. 曾经被写入控制台。

What am I missing? 我想念什么? Is there some kind of idiom I should be following? 我应该遵循某种成语吗?

By reading the source and some general experimentation, I figured out how to do a single asynchronous thing and then continue processing through the stream. 通过阅读源代码和一些常规实验,我了解了如何执行单个异步操作,然后继续在流中进行处理。 Basically, you use flatMap to replace the event from the asynchronous task with the stream you actually want to process. 基本上,您可以使用flatMap将异步任务中的事件替换为实际要处理的流。

Another quirk I didn't expect and which was throwing me off, was that _.pipeline won't work unless the original stream is fully consumed in the callback. 我没想到的另一个怪癖是使_.pipeline不起作用,除非原始流在回调中被完全使用。 That's why it won't work simply putting in a _.map and log stuff (which was how I tried to debug it). 这就是为什么仅将_.map和日志内容(这就是我尝试对其进行调试的方式)放入后就无法正常工作的原因。 Instead one needs to make sure to have an each or done at the end. 取而代之的是,需要确保each或最后done Below is a minimal example: 下面是一个最小的示例:

export default _ => _.pipeline( stream => {
  return _(promiseReturningFunction())
    .tap(_ => process.stdout.write('.'))
    .flatMap(_ => stream)
    .each(_ => process.stdout.write('-'));
});

// Will produce something like the following when called with a non-empty stream.
// Note the lone '.' in the beginning.
// => .-------------------

Basically, a '.' 基本上是一个“。” is output when the async function is done, and a '-' for every object of the stream. 完成异步功能后,将输出,对于流的每个对象均输出“-”。

Hopefully, this saves someone some time. 希望这可以节省一些时间。 Took embarrassingly long for me to figure this out. 我尴尬地花了很长时间才弄清楚这一点。 ^^ ^^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM