Я начинаю использовать RxJS и не понимаю, почему в этом примере нам нужно использовать такую функцию, как flatMap
или concatAll
; где здесь массив массивов?
var requestStream = Rx.Observable.just('https://api.github.com/users');
var responseMetastream = requestStream
.flatMap(function(requestUrl) {
return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
});
responseMetastream.subscribe(url => {console.log(url)})
Если кто-то сможет наглядно объяснить происходящее, это будет очень полезно.
javascript
rxjs
user233232
источник
источник
flatMap
бы назвалиmapThenFlatten
, то было бы меньше путаницы.Ответы:
Когда я начал смотреть,
Rxjs
я тоже наткнулся на этот камень. Мне помогло следующее:flatMap
: http://reactivex.io/documentation/operators/flatmap.htmlflatMap
там, вы должны посмотретьmergeMap
вместо этого (другое имя).наконец, глядя на информацию о типе из RxJava. Не набираемый Javascript здесь не помогает. В основном if
Observable<T>
обозначает наблюдаемый объект, который передает значения типа T, затемflatMap
принимает функцию типа вT' -> Observable<T>
качестве аргумента и возвращаетObservable<T>
.map
принимает функцию типаT' -> T
и возвращаетObservable<T>
.Возвращаясь к вашему примеру, у вас есть функция, которая производит обещания из строки URL. Итак
T' : string
, иT : promise
. И из того, что мы сказали ранееpromise : Observable<T''>
, так чтоT : Observable<T''>
сT'' : html
. Если вы поместите эту функцию создания обещанийmap
, вы получитеObservable<Observable<T''>>
то, что вам нужноObservable<T''>
: вы хотите, чтобы наблюдаемый объект испускалhtml
значения.flatMap
называется так, потому что он сглаживает (удаляет наблюдаемый слой) результат изmap
. В зависимости от вашего опыта, это может быть китайский язык, но мне все стало кристально ясно после ввода информации и рисунка отсюда: http://reactivex.io/documentation/operators/flatmap.html .источник
return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl));
вreturn jQuery.getJSON(requestUrl);
качествеflatMap
также принимает функцию селектора , которая возвращает обещание т.е. функцию типаT' -> Promise
.T’ -> T
? Я понимаю, чтоT
это общее, но что такое апостроф и не жирная стрелка?['a','b','c'].flatMap(function(e) { return [e, e+ 'x', e+ 'y', e+ 'z' ]; }); //['a', 'ax', 'ay', 'az', 'b', 'bx', 'by', 'bz', 'c', 'cx', 'cy', 'cz'] ['a','b','c'].map(function(e) { return [e, e+ 'x', e+ 'y', e+ 'z' ]; }); //[Array[4], Array[4], Array[4]]
Вы используете flatMap, когда у вас есть Observable, результаты которого больше Observable.
Если у вас есть наблюдаемое, которое создается другим наблюдаемым, вы не можете фильтровать, уменьшать или отображать его напрямую, потому что у вас есть Observable, а не данные. Если вы создаете наблюдаемое, выбирайте flatMap вместо map; тогда с тобой все в порядке.
Как и во втором фрагменте, если вы выполняете асинхронную операцию, вам необходимо использовать flatMap.
var source = Rx.Observable.interval(100).take(10).map(function(num){ return num+1 }); source.subscribe(function(e){ console.log(e) })
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
var source = Rx.Observable.interval(100).take(10).flatMap(function(num){ return Rx.Observable.timer(100).map(() => num) }); source.subscribe(function(e){ console.log(e) })
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.1/Rx.min.js"></script>
источник
Люди склонны чрезмерно усложнять вещи , давая определение, которое гласит:
Клянусь, это определение до сих пор меня смущает, но я объясню его самым простым способом, используя пример
Наша ситуация : у нас есть наблюдаемый объект, который возвращает данные (простой URL-адрес), который мы собираемся использовать для выполнения HTTP-вызова, который вернет наблюдаемый объект, содержащий нужные нам данные, поэтому вы можете визуализировать ситуацию следующим образом:
Observable 1 |_ Make Http Call Using Observable 1 Data (returns Observable_2) |_ The Data We Need
поэтому, как вы можете видеть, мы не можем напрямую получить данные, которые нам нужны, поэтому первый способ получить данные мы можем использовать обычные подписки, например:
Observable_1.subscribe((URL) => { Http.get(URL).subscribe((Data_We_Need) => { console.log(Data_We_Need); }); });
это работает, но, как вы можете видеть, мы должны вложить подписки, чтобы получить наши данные, в настоящее время это неплохо, но представьте, что у нас есть 10 вложенных подписок, обслуживание которых станет невозможным.
поэтому лучший способ справиться с этим - просто использовать оператор,
flatMap
который будет делать то же самое, но заставляет нас избегать этой вложенной подписки:Observable_1 .flatMap(URL => Http.get(URL)) .subscribe(Data_We_Need => console.log(Data_We_Need));
источник
flatMap
преобразовать элементы, излучаемые Observable, в новые Observable, а затем сгладить выбросы из них в один Observable.Ознакомьтесь с приведенным ниже сценарием, где
get("posts")
возвращается Observable, который "сглаживается"flatMap
.myObservable.map(e => get("posts")).subscribe(o => console.log(o)); // this would log Observable objects to console. myObservable.flatMap(e => get("posts")).subscribe(o => console.log(o)); // this would log posts to console.
источник
Просто:
[1,2,3].map(x => [x, x * 10]) // [[1, 10], [2, 20], [3, 30]] [1,2,3].flatMap(x => [x, x * 10]) // [1, 10, 2, 20, 3, 30]]
источник
Это не массив массивов. Это наблюдаемое из наблюдаемых.
Следующее возвращает наблюдаемый поток строки.
requestStream .map(function(requestUrl) { return requestUrl; });
Хотя это возвращает наблюдаемый поток наблюдаемого потока json
requestStream .map(function(requestUrl) { return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl)); });
flatMap
автоматически сглаживает наблюдаемое, чтобы мы могли непосредственно наблюдать за потоком jsonисточник
flatMap
(иmap
) не относятся к массивам. Эти операции можно определить в любом универсальном контейнере или оболочке, включая массивы, словари, «необязательные элементы», реактивные потоки, обещания, указатели и даже сами функции. Это новое свойство математической конструкции, называемой монадой. Все приведенные выше примеры соответствуют требованиям для монады, поэтому всем им можно дать определениеmap
иflatMap
(с некоторыми оговорками).Здесь показана эквивалентная реализация flatMap с использованием подписок.
Без flatMap:
this.searchField.valueChanges.debounceTime(400) .subscribe( term => this.searchService.search(term) .subscribe( results => { console.log(results); this.result = results; } ); );
С помощью flatMap:
this.searchField.valueChanges.debounceTime(400) .flatMap(term => this.searchService.search(term)) .subscribe(results => { console.log(results); this.result = results; });
http://plnkr.co/edit/BHGmEcdS5eQGX703eRRE?p=preview
Надеюсь, это поможет.
Оливье.
источник
Observable - это объект, который генерирует поток событий: Next, Error и Completed.
Когда ваша функция возвращает Observable, она возвращает не поток, а экземпляр Observable.
flatMap
Оператор просто переводит этот экземпляр в поток.Это поведение по
flatMap
сравнению сmap
: Выполнить данную функцию и преобразовать полученный объект в поток.источник
С помощью flatMap
var requestStream = Rx.Observable.just('https://api.github.com/users'); var responseMetastream = requestStream .flatMap(function(requestUrl) { return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl)); }); responseMetastream.subscribe(json => {console.log(json)})
Без FlatMap
var requestStream = Rx.Observable.just('https://api.github.com/users'); var responseMetastream = requestStream .map(function(requestUrl) { return Rx.Observable.fromPromise(jQuery.getJSON(requestUrl)); }); responseMetastream.subscribe(jsonStream => { jsonStream.subscribe(json => {console.log(json)}) })
источник
Я не дурак, но мне пришлось прочитать это 10 раз, но до сих пор не понимаю. Когда я читаю фрагмент кода:
[1,2,3].map(x => [x, x * 10]) // [[1, 10], [2, 20], [3, 30]] [1,2,3].flatMap(x => [x, x * 10]) // [1, 10, 2, 20, 3, 30]
тогда я мог понять, что происходит, он делает две вещи:
*) Слово преобразования говорит, что предмет может быть преобразован во что-нибудь еще.
Тогда становится ясно, что оператор слияния выполняет сглаживание без отображения. Почему бы не назвать это mergeMap ? Похоже, что для flatMap также существует Alias mergeMap с таким именем .
источник