[英]Apply several functions to each element in a stream
我正在尝试采用流元素,并一次将一个元素应用一系列功能。 每个功能都是几种异步操作之一(下载,图像转换,通过网络上传等)。 这些库使用不同的API(一些Promises,一些回调),因此,如果我能弄清楚如何实现此目的,则使用Observables可以简化API。
我正在尝试使用rxjs
找出正确执行此操作的语法,这是我到目前为止尝试过的:
const Rx = require('rxjs');
const { download } = require('./lib/images');
const { transform } = require('./lib/operations');
const program = require('./lib/bin');
const util = require('./lib/util');
const files = util.fixFileExtensions(program.args);
const files$ = Rx.Observable.fromPromise(getMetadata(files));
const download$ = Rx.Observable.bindCallback(download);
const transform$ = Rx.Observable.fromPromise(transform);
// Take the files, apply the download$ and transform$ to each element in the stream
files$
.map(download$)
.map(transform$)
.subscribe();
但是我的语法已关闭,并且出现错误。 使这项工作有效的语法是什么?
编辑从当前的评论和答案来看,这是更新的内容,但仍未将download
的输出传递给transform
。 这是我所拥有的:
function download({id, name}, callback) {
const credentials = {....};
const filePath = `/path/to/tmp/${name}`;
const stream = fs.createWriteStream(filePath);
authenticate(credentials, err {
if (err) throw err;
files.download(...., (err, res) => {
res.data
.on('end', () => callback(filePath))
.on('error', err => throw err)
.on('data', /* write to file */)
.pipe(stream)
});
});
}
function transform(filename, callback) {
const transformations = /* load transformations */;
const result = transformations.map(t => applyTransformation(filename, t));
callback(result);
}
const download$ = Rx.Observable.bindCallback(download);
const transform$ = Rx.Observable.bindCallback(transform);
files$
.flatMap(file => file)
.switchMap(download$)
.map(transform$)
.subscribe(console.log, console.error, () => console.log('map is done'));
这从我的download
函数抛出一个错误,说TypeError: callback is not a function
,因此正确调用了download
,但是未将其输出传递给transform
最后,您需要使用switchMap来应用异步操作。 Switchmap将订阅内部的Observable并对其进行解析:
files$
.switchMap(download$)
.switchMap(transform$)
.subscribe();
如果订阅中需要下载值,则必须传递内部值:
files$
.switchMap(download$)
.switchMap(transform$, (outerValue, innerValue) => {outerValue, innerValue})
.subscribe(valueOfDonwload => console.log(valueOfDonwload));
将其留在后头供您参考,David的回复是正确的,但仍然行不通。 我仔细阅读了此博客文章,使之能够工作,该文章显示了如何使用可观察序列: https : //medium.freecodecamp.org/rxjs-and-node-8f4e0acebc7c
这是我最终的代码:
files$
.flatMap(file => file)
.switchMap(input => download$(input))
.mergeMap(downloadedFile => transform$(downloadedFile))
.subscribe(console.log, console.error, () => console.log('map is done'));
我没想到的一件事是我的.switchMap(input => download$(input))
似乎不等同于.switchMap(download$)
; 后一种语法引发错误TypeError: callback is not a function
第二个好奇点是.flatMap
和.mergeMap
是别名-它们具有相同的功能,这似乎归结为“获取序列中先前Observable的输出”。 这里有一个细微差别,在我的代码中,第一个flatMap
从先前的Observable中拆分出数组,第二个flatMap
( mergeMap
)获取先前的输出,并将其提供为transform$
输入。 由于语法没有什么不同,除非在默认情况下执行此操作,否则我不确定其工作原理
现在,将上传功能绑定到此傻瓜,并继续完全自动化我的附带演出。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.