flatMap() vs map()
map() metodundan farklı olarak asenkron çalışır. Açıklaması şöyle
There is always a question, is there a difference between flatMap and map? Well yes there is a difference.- flatMap is used for non blocking operation in this case an operation that will return a Mono or Flux.- map is used for blocking operation that can be done in fixed time. An example would be transforming an object.
Örnek
Şöyle yaparız. Burada Person nesnesini EnhancedPerson nesnesine çevirme işi senkron yapılır. Ancak veri tabanına kaydetme işinin ne kadar süreceği belirsiz olduğu için asenkron yapılır
return Mono.just(Person("name", "age:12")).map { person ->EnhancedPerson(person, "id-set", "savedInDb")}.flatMap { person ->reactiveMongoDb.save(person)};
Örnek
Şöyle yaparız
//Create a person object with names and age Person obj = new Person("firstname", "lastname", 20); return Mono.just(obj) .map { person -> AdminPerson(person, "admin") // blocking transform the person to an admin }.flatMap { person -> personRepository.save(person) // Non blocking save to database }
Örnek - chained flatMap
Şöyle yaparız
@GetMapping("/students/course/{studentID}/{courseID}") Mono<CourseWork> addNewCourseNoChain(Long studentID, @PathVariable Long courseID) { return studentsRepository.findById(studentID) .flatMap(students -> { //Update student details students.setUpdated_on(System.currentTimeMillis()); return studentsRepository.save(students); }).flatMap(updatedStudent -> { //Create a new course for student CourseWork courseWork = getCoursework(updatedStudent.getId(), courseID); return courseWorkRepository.save(courseWork); }); }
Örnek - subscribe farkı
Elimizde şöyle bir kod olsun. service::update() çalışmaz. Çünkü o da bir Mono dönüyor ve bu dönülen Mono nesnesine subscribe olunmadı
Düzeltmek için şöyle yaparız. Bu sefer çalışır çünkü flatMap() verilen lambda'nın döndürdüğü Mono'ya subscribe olur.interface Service {Mono<String> create(String s);Mono<Void> update(String s);}class Foo {private final Service service;Mono<Void> problem() {return service.create("foo").doOnNext(service::update).then();}}
interface Service {Mono<String> create(String s);Mono<Void> update(String s);}class Foo {private final Service service;Mono<Void> problem() {return service.create("foo").flatMap(service::update)}}