เมื่อใดที่ควรใช้ RxJava Observable และเมื่อโทรกลับอย่างง่ายบน Android


260

ฉันกำลังทำงานกับเครือข่ายสำหรับแอปของฉัน ดังนั้นผมจึงตัดสินใจที่จะลองของจัตุรัสติดตั้งเพิ่ม ฉันเห็นว่าพวกเขาสนับสนุนเรียบง่ายCallback

@GET("/user/{id}/photo")
void getUserPhoto(@Path("id") int id, Callback<Photo> cb);

และ RxJava's Observable

@GET("/user/{id}/photo")
Observable<Photo> getUserPhoto(@Path("id") int id);

ทั้งคู่ดูคล้ายกันตั้งแต่แรกเห็น แต่เมื่อนำไปใช้งานมันน่าสนใจ ...

ในขณะที่การใช้งานการโทรกลับง่ายจะมีลักษณะคล้ายกับนี้

api.getUserPhoto(photoId, new Callback<Photo>() {
    @Override
    public void onSuccess() {
    }
});

ซึ่งค่อนข้างง่ายและตรงไปตรงมา และด้วยObservableอย่างรวดเร็วได้รับ verbose และค่อนข้างซับซ้อน

public Observable<Photo> getUserPhoto(final int photoId) {
    return Observable.create(new Observable.OnSubscribeFunc<Photo>() {
        @Override
        public Subscription onSubscribe(Observer<? super Photo> observer) {
            try {
                observer.onNext(api.getUserPhoto(photoId));
                observer.onCompleted();
            } catch (Exception e) {
                observer.onError(e);
            }

            return Subscriptions.empty();
        }
    }).subscribeOn(Schedulers.threadPoolForIO());
}

และนั่นไม่ใช่มัน คุณยังต้องทำอะไรเช่นนี้:

Observable.from(photoIdArray)
        .mapMany(new Func1<String, Observable<Photo>>() {
            @Override
            public Observable<Photo> call(Integer s) {
                return getUserPhoto(s);
            }
        })
        .subscribeOn(Schedulers.threadPoolForIO())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Photo>() {
            @Override
            public void call(Photo photo) {
                //save photo?
            }
        });

ฉันทำอะไรบางอย่างหายไปหรือเปล่า หรือเป็นกรณีที่ใช้ผิดObservableหรือเปล่า? เมื่อใดที่ / ควรจะชอบการObservableโทรกลับอย่างง่าย?

ปรับปรุง

ใช้ retrofit ง่ายกว่าตัวอย่างข้างต้นเป็น @Niels แสดงให้เห็นในคำตอบของเขาหรือเจควอร์ตันเป็นตัวอย่างโครงการU2020 แต่โดยพื้นฐานแล้วคำถามยังคงเหมือนเดิม - เมื่อใดควรใช้วิธีหนึ่งหรืออีกวิธีหนึ่ง


คุณสามารถปรับปรุงการเชื่อมโยงคุณไปยังไฟล์ที่คุณกำลังพูดถึงใน U2020
letroll

มันยังคงทำงานอยู่ ...
Martynas Jurkus

4
ผู้ชายฉันมีความคิดเหมือนกันอย่างแน่นอนเมื่อฉันอ่าน RxJava เป็นสิ่งใหม่ ฉันอ่านตัวอย่างการติดตั้งเพิ่มเติม (เพราะฉันคุ้นเคยกับมันมาก) ของคำของ่าย ๆ และมันก็เป็นรหัสสิบหรือสิบห้าบรรทัดและปฏิกิริยาแรกของฉันคือคุณต้องล้อเล่นฉัน = / ฉันยังไม่สามารถระบุได้ว่าสิ่งนี้จะแทนที่อีเวนต์บัสได้อย่างไรในขณะที่อีเวนต์บัสแยกตัวคุณจากการสังเกตการณ์และ rxjava แนะนำการเชื่อมต่ออีกครั้งเว้นแต่ว่าฉันเข้าใจผิด
Lo-Tan

คำตอบ:


348

สำหรับเครือข่ายแบบง่าย ๆ ข้อดีของ RxJava over Callback นั้นมี จำกัด มาก ตัวอย่าง getUserPhoto อย่างง่าย:

RxJava:

api.getUserPhoto(photoId)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Photo>() {
            @Override
            public void call(Photo photo) {
               // do some stuff with your photo 
            }
     });

โทรกลับ:

api.getUserPhoto(photoId, new Callback<Photo>() {
    @Override
    public void onSuccess(Photo photo, Response response) {
    }
});

ตัวแปร RxJava นั้นไม่ได้ดีไปกว่าชุดโทรกลับ สำหรับตอนนี้เราไม่สนใจการจัดการข้อผิดพลาด มาถ่ายรูปรายการกัน

RxJava:

api.getUserPhotos(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<List<Photo>, Observable<Photo>>() {
    @Override
    public Observable<Photo> call(List<Photo> photos) {
         return Observable.from(photos);
    }
})
.filter(new Func1<Photo, Boolean>() {
    @Override
    public Boolean call(Photo photo) {
         return photo.isPNG();
    }
})
.subscribe(
    new Action1<Photo>() {
    @Override
        public void call(Photo photo) {
            list.add(photo)
        }
    });

โทรกลับ:

api.getUserPhotos(userId, new Callback<List<Photo>>() {
    @Override
    public void onSuccess(List<Photo> photos, Response response) {
        List<Photo> filteredPhotos = new ArrayList<Photo>();
        for(Photo photo: photos) {
            if(photo.isPNG()) {
                filteredList.add(photo);
            }
        }
    }
});

ตอนนี้ตัวแปร RxJava ยังไม่เล็ก แต่ด้วยแลมบ์ดามันจะเข้าใกล้กับตัวแปรโทรกลับมากขึ้น นอกจากนี้หากคุณมีสิทธิ์เข้าถึงฟีด JSON มันจะเป็นเรื่องแปลกที่จะเรียกคืนรูปภาพทั้งหมดเมื่อคุณแสดง PNG เท่านั้น เพียงปรับฟีดไปที่มันจะแสดงเฉพาะ PNG

ข้อสรุปแรก

ไม่ทำให้ codebase ของคุณเล็กลงเมื่อคุณโหลด JSON แบบง่ายที่คุณเตรียมไว้ให้อยู่ในรูปแบบที่ถูกต้อง

ตอนนี้เรามาทำให้เรื่องน่าสนใจขึ้นอีกหน่อย สมมติว่าคุณไม่เพียง แต่ต้องการดึง userPhoto เท่านั้น แต่คุณมี Instagram-clone และคุณต้องการที่จะดึง 2 JSON: 1. getUserDetails () 2. getUserPhotos ()

คุณต้องการโหลด JSON สองตัวนี้พร้อมกันและเมื่อโหลดทั้งคู่แล้วเพจควรจะปรากฏขึ้น ตัวแปรโทรกลับจะยากขึ้นอีกนิด: คุณต้องสร้างการติดต่อกลับ 2 ครั้งจัดเก็บข้อมูลในกิจกรรมและหากโหลดข้อมูลทั้งหมดแล้วให้แสดงหน้า:

โทรกลับ:

api.getUserDetails(userId, new Callback<UserDetails>() {
    @Override
    public void onSuccess(UserDetails details, Response response) {
        this.details = details;
        if(this.photos != null) {
            displayPage();
        }
    }
});

api.getUserPhotos(userId, new Callback<List<Photo>>() {
    @Override
    public void onSuccess(List<Photo> photos, Response response) {
        this.photos = photos;
        if(this.details != null) {
            displayPage();
        }
    }
});

RxJava:

private class Combined {
    UserDetails details;
    List<Photo> photos;
}


Observable.zip(api.getUserDetails(userId), api.getUserPhotos(userId), new Func2<UserDetails, List<Photo>, Combined>() {
            @Override
            public Combined call(UserDetails details, List<Photo> photos) {
                Combined r = new Combined();
                r.details = details;
                r.photos = photos;
                return r;
            }
        }).subscribe(new Action1<Combined>() {
            @Override
            public void call(Combined combined) {
            }
        });

เรากำลังจะไปที่ไหนซักแห่ง! ตอนนี้โค้ดของ RxJava ใหญ่พอ ๆ กับตัวเลือกการโทรกลับ รหัส RxJava นั้นแข็งแกร่งกว่า คิดว่าจะเกิดอะไรขึ้นถ้าเราต้องการโหลด JSON ตัวที่สาม (เช่นวิดีโอล่าสุด) RxJava ต้องการเพียงการปรับเปลี่ยนเล็กน้อยในขณะที่ตัวแปร Callback จำเป็นต้องปรับเปลี่ยนในหลาย ๆ ที่ (ในการติดต่อกลับแต่ละครั้งเราต้องตรวจสอบว่ามีการดึงข้อมูลทั้งหมดหรือไม่)

ตัวอย่างอื่น; เราต้องการสร้างฟิลด์เติมข้อความอัตโนมัติซึ่งโหลดข้อมูลโดยใช้ Retrofit เราไม่ต้องการทำเว็บคอลทุกครั้งที่ EditText มี TextChangedEvent เมื่อพิมพ์อย่างรวดเร็วเฉพาะองค์ประกอบสุดท้ายเท่านั้นที่ควรเรียกใช้ ใน RxJava เราสามารถใช้ตัวดำเนินการดีบั๊ก

inputObservable.debounce(1, TimeUnit.SECONDS).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                // use Retrofit to create autocompletedata
            }
        });

ฉันจะไม่สร้างตัวแปรโทรกลับ แต่คุณจะเข้าใจว่ามันใช้งานได้มากกว่า

สรุป: RxJava ยอดเยี่ยมมากเมื่อส่งข้อมูลเป็นสตรีม Retrofit Observable ผลักองค์ประกอบทั้งหมดในกระแสข้อมูลในเวลาเดียวกัน สิ่งนี้ไม่ได้มีประโยชน์โดยเฉพาะเมื่อเปรียบเทียบกับการติดต่อกลับ แต่เมื่อมีองค์ประกอบหลายอย่างผลักดันกระแสและเวลาที่แตกต่างกันและคุณต้องทำสิ่งที่เกี่ยวข้องกับเวลา RxJava ทำให้รหัสสามารถบำรุงรักษาได้มากขึ้น


6
คุณใช้คลาสinputObservableอะไร ฉันมีปัญหามากมายเกี่ยวกับการเปิดตัวและต้องการเรียนรู้เพิ่มเติมเกี่ยวกับโซลูชันนี้
Migore

@Migore RxBindingโครงการมีโมดูล "แพลตฟอร์มผูกพัน" ที่ให้การเรียนเช่นRxView, RxTextViewฯลฯ inputObservableที่สามารถนำมาใช้สำหรับ
พายุหิมะ

@Niels คุณสามารถอธิบายวิธีเพิ่มการจัดการข้อผิดพลาดได้อย่างไร คุณสามารถสร้างผู้สมัครสมาชิกด้วย onCompleted, onError และ onNext ได้ไหมถ้าคุณทำ flatMap, Filter แล้วสมัคร? ขอบคุณมากสำหรับคำอธิบายที่ยิ่งใหญ่ของคุณ
Nicolas Jafelle

4
นี่เป็นตัวอย่างที่ยอดเยี่ยม!
Ye Lin Aung

3
คำอธิบายที่ดีที่สุดตลอดกาล!
เดนิสเนก

66

สิ่งที่สังเกตได้ทำไว้แล้วใน Retrofit ดังนั้นรหัสอาจเป็น:

api.getUserPhoto(photoId)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Action1<Photo>() {
         @Override
            public void call(Photo photo) {
                //save photo?
            }
     });

5
ใช่ แต่คำถามคือเมื่อใดที่จะชอบอีกคนหนึ่ง?
Christopher Perry

7
ดังนั้นวิธีนี้ดีกว่าโทรกลับง่าย
Martynas Jurkus

14
@MartynasJurkus observables จะมีประโยชน์หากคุณต้องการเชื่อมโยงหลายฟังก์ชั่น ตัวอย่างเช่นผู้โทรต้องการรับภาพที่ถูกครอบตัดเป็นขนาด 100x100 api อาจส่งคืนรูปภาพขนาดใดก็ได้ดังนั้นคุณสามารถแมป getUserPhoto ที่สังเกตได้กับ ResizedPhotoObservable อื่น - ผู้โทรจะได้รับแจ้งเมื่อมีการปรับขนาดเท่านั้น หากคุณไม่ต้องการใช้มันอย่าบังคับให้ใช้
ataulm

2
หนึ่งความคิดเห็นเล็กน้อย ไม่จำเป็นต้องโทรหา. สมัครสมาชิก (Schedulers.io ()) เนื่องจาก RetroFit ดูแลเรื่องนี้อยู่แล้ว - github.com/square/retrofit/issues/430 (ดูคำตอบของ Jake)
hiBrianLee

4
@MartynasJurkus นอกจากนี้สิ่งที่พูดโดย ataulm ซึ่งแตกต่างจากCallbackคุณสามารถยกเลิกการสมัครObserveableดังนั้นจึงหลีกเลี่ยงปัญหาวงจรชีวิตทั่วไป
Dmitry Zaytsev

35

ในกรณีของ getUserPhoto () ข้อดีสำหรับ RxJava นั้นไม่ค่อยดีนัก แต่ลองมาอีกตัวอย่างหนึ่งเมื่อคุณได้รับรูปภาพทั้งหมดสำหรับผู้ใช้ แต่เมื่อรูปภาพเป็น PNG และคุณไม่สามารถเข้าถึง JSON เพื่อทำการกรองบนเซิร์ฟเวอร์

api.getUserPhotos(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<List<Photo>, Observable<Photo>>() {
    @Override
    public Observable<Photo> call(List<Photo> photos) {
         return Observable.from(photos);
    }
})
.filter(new Func1<Photo, Boolean>() {
    @Override
    public Boolean call(Photo photo) {
         return photo.isPNG();
    }
})
.subscribe(
    new Action1<Photo>() {
    @Override
        public void call(Photo photo) {
            // on main thread; callback for each photo, add them to a list or something.
            list.add(photo)
        }
    }, 
    new Action1<Throwable>() {
    @Override
        public void call(Throwable throwable) {
            // on main thread; something went wrong
            System.out.println("Error! " + throwable);
        }
    }, 
    new Action0() {
        @Override
        public void call() {
            // on main thread; all photo's loaded, time to show the list or something.
        }
    });

ตอนนี้ JSON ส่งคืนรายการของ Photo เราจะแบนแผนที่ให้กับแต่ละรายการ ด้วยการทำเช่นนี้เราจะสามารถใช้วิธีการกรองเพื่อละเว้นรูปภาพที่ไม่ใช่ PNG หลังจากนั้นเราจะสมัครและรับการติดต่อกลับสำหรับภาพถ่ายแต่ละภาพข้อผิดพลาดแฮนด์เลอร์และการโทรกลับเมื่อทุกแถวเสร็จสมบูรณ์

จุด TLDRอยู่ที่นี่; การโทรกลับจะส่งคืนการโทรกลับเพื่อให้คุณประสบความสำเร็จและล้มเหลวเท่านั้น Obx RxJava ช่วยให้คุณสามารถทำแผนที่ลดกรองและอื่น ๆ อีกมากมาย


ก่อนปิดการสมัครสมาชิกและ observOn ไม่จำเป็นต้องมีการติดตั้งเพิ่ม มันจะทำการเรียกเครือข่ายแบบอะซิงโครนัสและแจ้งเตือนในเธรดเดียวกันกับผู้เรียก เมื่อคุณเพิ่ม RetroLambda และรับแลมบ์ดานิพจน์ก็จะยิ่งดีขึ้น

แต่ฉันสามารถทำได้ (ภาพตัวกรองคือ PNG) ใน. สมัครสมาชิก () เพราะเหตุใดฉันจึงควรใช้ตัวกรอง และไม่จำเป็นต้องใช้ใน flatmap
SERG

3
3 คำตอบจาก @Niels คนแรกตอบคำถาม ไม่มีประโยชน์สำหรับ 2nd
Raymond Chenon

คำตอบเดียวกับครั้งแรก
Mayank Sharma

27

ด้วย rxjava คุณสามารถทำสิ่งต่าง ๆ ได้มากขึ้นโดยใช้รหัสน้อยลง

สมมติว่าคุณต้องการใช้การค้นหาทันทีในแอปของคุณ ด้วยการโทรกลับคุณมีความกังวลเกี่ยวกับการยกเลิกการสมัครคำขอก่อนหน้าและสมัครสมาชิกใหม่จัดการการวางแนวเปลี่ยนตัวคุณเอง ... ฉันคิดว่ามันเป็นรหัสจำนวนมากและ verbose มากเกินไป

ด้วย rxjava ง่ายมาก

public class PhotoModel{
  BehaviorSubject<Observable<Photo>> subject = BehaviorSubject.create(...);

  public void setUserId(String id){
   subject.onNext(Api.getUserPhoto(photoId));
  }

  public Observable<Photo> subscribeToPhoto(){
    return Observable.switchOnNext(subject);
  }
}

ถ้าคุณต้องการใช้การค้นหาแบบทันทีคุณเพียงแค่ฟัง TextChangeListener และโทรไป photoModel.setUserId(EditText.getText());

ในเมธอด onCreate ของ Fragment หรือกิจกรรมที่คุณสมัครเป็นสมาชิก Observable ที่ส่งคืน photoModel.subscribeToPhoto () จะส่งคืน Observable ที่จะปล่อยไอเท็มที่เปล่งออกมาโดย Observable ล่าสุด (คำขอ) เสมอ

AndroidObservable.bindFragment(this, photoModel.subscribeToPhoto())
                 .subscribe(new Action1<Photo>(Photo photo){
      //Here you always receive the response of the latest query to the server.
                  });

นอกจากนี้หาก PhotoModel เป็น Singleton คุณไม่จำเป็นต้องกังวลเกี่ยวกับการเปลี่ยนแปลงการวางแนวเนื่องจาก BehaviorSubject ปล่อยการตอบสนองของเซิร์ฟเวอร์ล่าสุดไม่ว่าคุณจะสมัครเมื่อใดก็ตาม

ด้วยรหัสบรรทัดนี้เราได้ทำการค้นหาและจัดการการเปลี่ยนแปลงการวางแนว คุณคิดว่าคุณสามารถใช้สิ่งนี้กับการเรียกกลับด้วยรหัสน้อย? ฉันสงสัยมัน.


คุณไม่คิดว่าจะทำให้ชั้นเรียน PhotoModel กลายเป็น Singleton หรือไม่? ลองนึกภาพว่ามันไม่ใช่โปรไฟล์ผู้ใช้ แต่เป็นชุดรูปถ่ายสำหรับผู้ใช้หลายคนเราจะไม่ได้รับเฉพาะรูปถ่ายของผู้ใช้ที่ร้องขอล่าสุดใช่หรือไม่ นอกจากนี้การขอข้อมูลเกี่ยวกับการเปลี่ยนทิศทางทุกครั้งทำให้ฉันรู้สึกว่าคุณคิดอย่างไร?
Farid

2

เรามักจะไปกับตรรกะดังต่อไปนี้:

  1. หากเป็นการโทรแบบตอบกลับเดียวแบบง่ายการโทรกลับหรืออนาคตดีกว่า
  2. หากเป็นการโทรที่ตอบกลับหลายรายการ (สตรีม) หรือเมื่อมีการโต้ตอบที่ซับซ้อนระหว่างการโทรที่แตกต่างกัน (ดูที่ @Niels ' คำตอบ ) แสดงว่าสังเกตได้ดีกว่า

1

จากตัวอย่างและข้อสรุปในคำตอบอื่น ๆ ฉันคิดว่าไม่มีความแตกต่างใหญ่สำหรับงานหนึ่งหรือสองขั้นตอนง่าย ๆ อย่างไรก็ตามการติดต่อกลับนั้นเรียบง่ายและตรงไปตรงมา RxJava ซับซ้อนและใหญ่เกินไปสำหรับงานง่ายๆ มีวิธีการแก้ปัญหาที่สามคือAbacusUtil ให้ฉันใช้กรณีการใช้งานด้านบนด้วยโซลูชันทั้งสาม: การโทรกลับ, RxJava, CompletableFuture (AbacusUtil) ด้วยRetrolambda :

ดึงรูปภาพจากเครือข่ายและบันทึก / แสดงบนอุปกรณ์:

// By Callback
api.getUserPhoto(userId, new Callback<Photo>() {
    @Override
    public void onResponse(Call<Photo> call, Response<Photo> response) {
        save(response.body()); // or update view on UI thread.
    }

    @Override
    public void onFailure(Call<Photo> call, Throwable t) {
        // show error message on UI or do something else.
    }
});

// By RxJava
api.getUserPhoto2(userId) //
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(photo -> {
            save(photo); // or update view on UI thread.
        }, error -> {
            // show error message on UI or do something else.
        });

// By Thread pool executor and CompletableFuture.
TPExecutor.execute(() -> api.getUserPhoto(userId))
        .thenRunOnUI((photo, error) -> {
            if (error != null) {
                // show error message on UI or do something else.
            } else {
                save(photo); // or update view on UI thread.
            }
        });

โหลดรายละเอียดผู้ใช้และรูปถ่ายในแบบคู่ขนาน

// By Callback
// ignored because it's little complicated

// By RxJava
Observable.zip(api.getUserDetails2(userId), api.getUserPhoto2(userId), (details, photo) -> Pair.of(details, photo))
        .subscribe(p -> {
            // Do your task.
        });

// By Thread pool executor and CompletableFuture.
TPExecutor.execute(() -> api.getUserDetails(userId))
          .runOnUIAfterBoth(TPExecutor.execute(() -> api.getUserPhoto(userId)), p -> {
    // Do your task
});

4
OP ไม่ขอคำแนะนำสำหรับห้องสมุดใหม่
forresthopkinsa

1

โดยส่วนตัวฉันชอบใช้ Rx เพื่อรับการตอบกลับของ api ในกรณีที่ฉันต้องทำตัวกรองแผนที่หรืออะไรทำนองนั้นกับข้อมูลหรือในกรณีที่ฉันต้องทำการเรียก api อีกครั้งตามการตอบรับสายก่อนหน้า


0

ดูเหมือนว่าคุณกำลังสร้างวงล้อใหม่สิ่งที่คุณกำลังทำอยู่ได้ถูกนำไปใช้ในการติดตั้งเพิ่ม

ตัวอย่างเช่นคุณสามารถดู retrofit ของRestAdapterTest.javaที่พวกเขากำหนดอินเตอร์เฟซกับสังเกตเป็นชนิดกลับมาแล้วใช้มัน


ขอบคุณสำหรับคำตอบ. ฉันเห็นสิ่งที่คุณพูด แต่ฉันยังไม่แน่ใจว่าฉันจะใช้สิ่งนี้อย่างไร คุณสามารถให้ตัวอย่างง่ายๆโดยใช้การติดตั้งเพิ่มเติมที่มีอยู่เพื่อที่ฉันจะให้รางวัลแก่คุณได้หรือไม่?
Yehosef

@Yehosef มีคนลบความคิดเห็นของพวกเขาหรือคุณหลอกว่าเป็น OP? ))
Farid

คุณสามารถให้รางวัลกับคำถามของคนอื่นได้ เมื่อฉันถามสิ่งนี้ฉันต้องการคำตอบของคำถามจริงๆ - ดังนั้นฉันจึงเสนอเงินรางวัล หากคุณวางตัวบนรางวัลความโปรดปรานคุณจะเห็นว่ามันได้รับรางวัลจากฉัน
Yehosef

0

เมื่อคุณสร้างแอพเพื่อความสนุกโครงการสัตว์เลี้ยงหรือ POC หรือต้นแบบที่ 1 คุณใช้คลาส Android / Java หลักอย่างง่ายเช่นการเรียกกลับงาน async, วนรอบหัวข้อ ฯลฯ พวกเขาจะง่ายต่อการใช้และไม่จำเป็นต้องมี การรวม lib บุคคลที่สาม การรวมไลบรารีขนาดใหญ่เพียงเพื่อสร้างโครงการที่ไม่สามารถเปลี่ยนแปลงได้ในเวลาเพียงเล็กน้อยนั้นไร้เหตุผลเมื่อสิ่งที่คล้ายคลึงกันสามารถทำได้ทันที

อย่างไรก็ตามสิ่งเหล่านี้ก็เหมือนมีดที่คมมาก การใช้สิ่งเหล่านี้ในสภาพแวดล้อมการผลิตนั้นยอดเยี่ยมอยู่เสมอ แต่ก็จะมีผลตามมา เป็นการยากที่จะเขียนรหัสที่ปลอดภัยพร้อมกันหากคุณไม่คุ้นเคยกับ Clean coding และหลักการ SOLID คุณจะต้องบำรุงรักษาสถาปัตยกรรมที่เหมาะสมเพื่ออำนวยความสะดวกในการเปลี่ยนแปลงในอนาคตและปรับปรุงประสิทธิภาพการทำงานของทีม

ในทางกลับกัน, ไลบรารีการทำงานพร้อมกันเช่น RxJava, Co-routines และอื่น ๆ จะถูกลองและทดสอบมากกว่าหนึ่งพันล้านครั้งเพื่อช่วยในการเขียนโค้ดที่พร้อมใช้งานสำหรับการผลิต ตอนนี้อีกครั้งไม่ใช่ว่าการใช้ไลบรารี่เหล่านี้คุณไม่ได้เขียนโค้ดที่เกิดขึ้นพร้อมกัน คุณยังอยู่ แต่ตอนนี้มันสามารถมองเห็นได้และบังคับใช้รูปแบบที่ชัดเจนสำหรับการเขียนโค้ดที่เกิดขึ้นพร้อมกันตลอดทั้ง codebase และที่สำคัญกว่านั้นตลอดทั้งทีมพัฒนาของคุณ

นี่คือประโยชน์หลักของการใช้เฟรมเวิร์กการทำงานพร้อมกันแทนคลาสคลาสหลักแบบเก่าที่จัดการกับการเกิดพร้อมกันแบบดิบ อย่างไรก็ตามอย่าเข้าใจฉันผิด ฉันเป็นผู้เชื่อที่ยิ่งใหญ่ในการ จำกัด การพึ่งพาของไลบรารีภายนอก แต่ในกรณีนี้คุณจะต้องสร้างกรอบงานที่กำหนดเองสำหรับรหัสฐานของคุณซึ่งเป็นงานที่ต้องใช้เวลามากและสามารถทำได้หลังจากผ่านประสบการณ์ขั้นสูงเท่านั้น ดังนั้นกรอบการทำงานพร้อมกันเป็นที่ต้องการมากกว่าการใช้คลาสธรรมดาเช่นการเรียกกลับ ฯลฯ


TL'DR

หากคุณใช้ RxJava สำหรับการเข้ารหัสพร้อมกันตลอดฐานรหัสเพียงใช้ RxJava Observable / Flowable คำถามที่ควรถามอย่างฉลาดคือฉันควรใช้ Observables to Flowables ถ้าไม่เช่นนั้นไปข้างหน้าและใช้ callable

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.