[英]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.