簡體   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