繁体   English   中英

将多个函数应用于流中的每个元素

[英]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中拆分出数组,第二个flatMapmergeMap )获取先前的输出,并将其提供为transform$输入。 由于语法没有什么不同,除非在默认情况下执行此操作,否则我不确定其工作原理

现在,将上传功能绑定到此傻瓜,并继续完全自动化我的附带演出。

暂无
暂无

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

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