পর্যবেক্ষণযোগ্যদের একটি তালিকা একত্রিত করুন এবং সমস্ত শেষ না হওয়া পর্যন্ত অপেক্ষা করুন


91

টি এল; ডিআর কিভাবে রূপান্তর করতে Task.whenAll(List<Task>)মধ্যে RxJava?

আমার বিদ্যমান কোডটি অ্যাসিক্রোনাস টাস্কগুলির একটি তালিকা তৈরি করতে বোল্ট ব্যবহার করে এবং অন্যান্য পদক্ষেপগুলি সম্পাদন করার আগে এই সমস্ত কাজ শেষ না হওয়া পর্যন্ত অপেক্ষা করে। মূলত, এটি একটি তৈরি করে List<Task>এবং একটি একক প্রদান করে Taskযা তালিকার সমস্ত কাজ সমাপ্ত হলে বোল্টস সাইটের উদাহরণ অনুসারে সম্পূর্ণ হিসাবে চিহ্নিত হয় ।

আমি এর Boltsসাথে প্রতিস্থাপন করতে চাই RxJavaএবং আমি এই পদ্ধতিটি ধরে নিয়ে যাচ্ছি async কার্যগুলির একটি তালিকা তৈরি করার পদ্ধতি (আকারটি আগে থেকে জানা যায় না) এবং সেগুলি একক মধ্যে মোড়ানো Observableসম্ভব, তবে কীভাবে তা আমি জানি না।

দেখছি চেষ্টা করেছি merge, zip, concatইত্যাদি ... কিন্তু না কাজ পেতে পারেন List<Observable>যে, আমি তৈরী করা চাই হিসাবে তারা সব কাজ মাত্র দুই থেকে গতি বাড়ানোর মনে Observablesএকটি সময়ে যদি আমি ডক্স সঠিকভাবে বুঝতে।

আমি শেখার চেষ্টা করছি RxJavaএবং এখনও এটিতে আমি খুব নতুন আছি তাই যদি এই স্পষ্ট প্রশ্ন হয় বা কোথাও ডক্সে ব্যাখ্যা করা হয় তবে আমাকে ক্ষমা করুন; আমি অনুসন্ধান করার চেষ্টা করেছি। কোন সাহায্যের অনেক প্রশংসা হবে।

উত্তর:


73

মনে হচ্ছে আপনি জিপ অপারেটরটির সন্ধান করছেন

এটি ব্যবহারের কয়েকটি ভিন্ন উপায় রয়েছে, সুতরাং আসুন একটি উদাহরণ দেখি। বলুন আমাদের কাছে বিভিন্ন ধরণের কয়েকটি সাধারণ পর্যবেক্ষণযোগ্য রয়েছে:

Observable<Integer> obs1 = Observable.just(1);
Observable<String> obs2 = Observable.just("Blah");
Observable<Boolean> obs3 = Observable.just(true);

তাদের সকলের জন্য অপেক্ষা করার সহজ উপায়টি হ'ল:

Observable.zip(obs1, obs2, obs3, (Integer i, String s, Boolean b) -> i + " " + s + " " + b)
.subscribe(str -> System.out.println(str));

নোট করুন যে জিপ ফাংশনে, প্যারামিটারগুলিতে কংক্রিটের ধরণ রয়েছে যা পর্যবেক্ষণযোগ্যদের জিপ করা হওয়ার ধরণের সাথে সামঞ্জস্য করে।

পর্যবেক্ষণযোগ্যদের একটি তালিকা জিপ করা সম্ভব, সরাসরি হয়:

List<Observable<?>> obsList = Arrays.asList(obs1, obs2, obs3);

Observable.zip(obsList, (i) -> i[0] + " " + i[1] + " " + i[2])
.subscribe(str -> System.out.println(str));

... বা একটিতে তালিকা মোড়ানো দ্বারা Observable<Observable<?>>:

Observable<Observable<?>> obsObs = Observable.from(obsList);

Observable.zip(obsObs, (i) -> i[0] + " " + i[1] + " " + i[2])
.subscribe(str -> System.out.println(str));

তবে, এই উভয় ক্ষেত্রেই জিপ ফাংশনটি কেবলমাত্র একটি একক Object[]প্যারামিটার গ্রহণ করতে পারে যেহেতু তালিকায় থাকা পর্যবেক্ষনের ধরণগুলি তাদের সংখ্যা হিসাবে আগে থেকে জানা যায় না। এর অর্থ হ'ল জিপ ফাংশনটিতে প্যারামিটারের সংখ্যাটি পরীক্ষা করতে হবে এবং সেগুলি অনুযায়ী সেগুলি নিক্ষেপ করতে হবে।

নির্বিশেষে, উপরোক্ত সমস্ত উদাহরণ শেষ পর্যন্ত মুদ্রণ করবে 1 Blah true

সম্পাদনা: জিপ ব্যবহার করার সময়, নিশ্চিত হয়ে নিন যে Observablesসমস্ত জিপ করা হচ্ছে একই সংখ্যক আইটেম নির্গত। উপরের উদাহরণগুলিতে তিনটি পর্যবেক্ষণযোগ্য একটি একক আইটেম নির্গত করে। যদি আমরা তাদেরকে এই জাতীয় কিছুতে পরিবর্তন করতে পারি:

Observable<Integer> obs1 = Observable.from(new Integer[]{1,2,3}); //Emits three items
Observable<String> obs2 = Observable.from(new String[]{"Blah","Hello"}); //Emits two items
Observable<Boolean> obs3 = Observable.from(new Boolean[]{true,true}); //Emits two items

তারপরে 1, Blah, Trueএবং 2, Hello, Trueজিপ ফাংশন (গুলি) এর মধ্যে কেবল একমাত্র আইটেম হবে। 3অন্যান্য পর্যবেক্ষণযোগ্যদের কাজ শেষ হওয়ায় আইটেমটি কখনই জিপ করা হবে না।


9
যদি কোনও কল ব্যর্থ হয় তবে এটি কাজ করবে না। সেক্ষেত্রে সমস্ত কল হারিয়ে যাবে।
স্টারউইন্ড0

4
@ স্টারওয়াইন্ড0 আপনি ব্যবহার করে ত্রুটি এড়িয়ে যেতে পারেন onErrorResumeNext, উদাহরণস্বরূপ:Observable.zip(ob1, ob2........).onErrorResumeNext(Observable.<String>empty())
ভুহং 3990

আমার যদি 100 টি পর্যবেক্ষণযোগ্য হয় তবে কী হবে?
ক্রিজিসটফ কুবিকি

80

flatMapআপনার যদি গতিশীল কাজের রচনা থাকে তবে আপনি ব্যবহার করতে পারেন । এটার মতো কিছু:

public Observable<Boolean> whenAll(List<Observable<Boolean>> tasks) {
    return Observable.from(tasks)
            //execute in parallel
            .flatMap(task -> task.observeOn(Schedulers.computation()))
            //wait, until all task are executed
            //be aware, all your observable should emit onComplemete event
            //otherwise you will wait forever
            .toList()
            //could implement more intelligent logic. eg. check that everything is successful
            .map(results -> true);
}

সমান্তরাল মৃত্যুদন্ডের আরও একটি ভাল উদাহরণ

দ্রষ্টব্য: ত্রুটি পরিচালনার জন্য আপনার প্রয়োজনীয়তাগুলি আমি সত্যিই জানি না। উদাহরণস্বরূপ, কেবলমাত্র একটি কাজ ব্যর্থ হলে কী করতে হবে। আমি মনে করি আপনার এই দৃশ্যটি যাচাই করা উচিত।


17
"তালিকার সমস্ত কাজ শেষ হলে" এই প্রশ্নের উত্তর বিবেচনা করে এটির গ্রহণযোগ্য উত্তর হওয়া উচিত। zipযে কোনও একটি কাজ শেষ হওয়ার সাথে সাথে সমাপ্তির বিষয়ে অবহিত করে এবং এইভাবে প্রযোজ্য নয়।
ব্যবহারকারী3707125

4
@ মাইডগটম: আপনি কি জাভা Sy সিনট্যাক্স (ল্যাম্বডা নয়) সংস্করণ দিয়ে উত্তরটি আপডেট করতে পারবেন?
সানাইড্রয়েড

4
@ পূজাগাইকওয়াদ লাম্বদার সাথে এটি আরও পাঠযোগ্য। new Func1<Observable<Boolean>, Observable<Boolean>>()...new Func1<List<Boolean>, Boolean>()
সবে

@ সোশিয়াল আরএক্সজাভা ২ সবচেয়ে খারাপ জিনিস যা আরএক্সজবা এর সাথে ঘটেছিল, হ্যাঁ
এওরোকিম

15

প্রস্তাবিত পরামর্শগুলির মধ্যে, জিপ () আসলে একে অপরের সাথে পর্যবেক্ষণযোগ্য ফলাফলগুলি একত্রিত করে, যা যা চেয়েছিল তা হতে পারে বা নাও হতে পারে, তবে প্রশ্নটিতে জিজ্ঞাসা করা হয়নি। প্রশ্নে, যা যা ছিল তা হ'ল প্রতিটি অপারেশনকে একের পর এক করে বা সমান্তরালভাবে (যা নির্দিষ্ট করা হয়নি, তবে লিঙ্কযুক্ত বোল্টসের উদাহরণটি ছিল সমান্তরাল ফাঁসির বিষয়ে) execution এছাড়াও, পর্যবেক্ষণযোগ্যদের কোনও সম্পূর্ণ হয়ে গেলে জিপ () তত্ক্ষণাত্ সম্পন্ন হবে, সুতরাং এটি প্রয়োজনীয়তা লঙ্ঘন করে।

পর্যবেক্ষণগুলির সমান্তরাল সম্পাদনের জন্য, অন্য উত্তরে উপস্থাপন করা ফ্ল্যাটম্যাপ () ঠিক আছে, তবে মার্জ () আরও সরল-এগিয়ে হবে। নোট করুন যে কোনও পর্যবেক্ষণযোগ্যদের ত্রুটির ভিত্তিতে মার্জটি প্রস্থান করবে, যদি আপনি বরং সমস্ত পর্যবেক্ষক শেষ না হওয়া পর্যন্ত প্রস্থান স্থগিত করেন, আপনি মার্জডেলিআরার () এ খুঁজছেন ।

একের পর একের জন্য, আমি মনে করি অবজারভেবলকনক্যাট () স্ট্যাটিক পদ্ধতিটি ব্যবহার করা উচিত। এর জাভাদোকটি এইভাবে জানিয়েছে:

কনক্যাট (জাভা.লং.ইরেটেবল> সিকোয়েন্সস) অবজার্ভেবলের এক অপরিবর্তনীয় স্থলকে একের পর এক পর্যবেক্ষণযোগ্য করে তোলে

আপনি যদি সমান্তরাল কার্যনির্বাহী না চান তবে আপনি যা করছেন তা কেমন লাগে।

এছাড়াও, যদি আপনি শুধুমাত্র আপনার টাস্ক সম্পন্ন করতে আগ্রহী হন, মান ফিরে না, আপনি সম্ভবত মধ্যে হওয়া উচিত Completable পরিবর্তে পর্যবেক্ষণযোগ্য

টিএলডিআর: একের পর এক কার্য সম্পাদনের জন্য এবং অনকম্প্লেশন ইভেন্টগুলি যখন তারা সম্পন্ন হয়, আমি মনে করি কমপ্লিটেবল কনক্যাট () সবচেয়ে উপযুক্ত best সমান্তরাল সম্পাদনের জন্য, কমলেটেবল.সামার () বা কমপ্লেটেবল.সেমারডেলিআরার () শব্দটির সমাধান হিসাবে মনে হচ্ছে। পূর্ববর্তীটি যে কোনও পরিপূরকটিতে ত্রুটি তত্ক্ষণাত্ বন্ধ হবে, পরেরটি তাদের সকলের মৃত্যুদন্ড কার্যকর করবে এমনকি যদি তাদের মধ্যে একটির ত্রুটি থাকে এবং কেবল তখনই ত্রুটিটি রিপোর্ট করে।


2

আপনি সম্ভবত zipঅপারেটরটির দিকে চেয়েছিলেন যা ২ টি পর্যবেক্ষণযোগ্যদের সাথে কাজ করে।

স্থির পদ্ধতিও রয়েছে Observable.zip। এটির একটি ফর্ম রয়েছে যা আপনার পক্ষে কার্যকর হবে:

zip(java.lang.Iterable<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)

আপনি আরও জন্য জাভাদোক পরীক্ষা করতে পারেন


2

কোটলিনের সাথে

Observable.zip(obs1, obs2, BiFunction { t1 : Boolean, t2:Boolean ->

})

ফাংশনটির আর্গুমেন্টগুলির জন্য টাইপটি সেট করা গুরুত্বপূর্ণ বা আপনার সংকলনের ত্রুটি রয়েছে

যুক্তির সংখ্যার সাথে শেষ যুক্তির ধরণের পরিবর্তন: 4 ফাংশন 4 এর জন্য 2 ফাংশন 3 এর জন্য বায়ফিউশন ...


1

আমি জাভাআরএক্স অবজারভেবলস এবং আরএক্সকোটলিনের সাথে কোটলিনে কয়েকটি গণনার হিভ কোড লিখছি। আমি পর্যবেক্ষণযোগ্যদের একটি তালিকা সম্পন্ন করতে এবং এর মধ্যে আমাকে অগ্রগতি এবং সর্বশেষ ফলাফলের সাথে আপডেট দিয়েছি observe শেষে এটি সেরা গণনার ফলাফল প্রদান করে। আমার সমস্ত সিপিইউ কর ব্যবহারের জন্য সমান্তরালে অবজার্ভেবলগুলি চালানো একটি অতিরিক্ত প্রয়োজন ছিল। আমি এই সমাধানটি দিয়ে শেষ করেছি:

@Volatile var results: MutableList<CalculationResult> = mutableListOf()

fun doALotOfCalculations(listOfCalculations: List<Calculation>): Observable<Pair<String, CalculationResult>> {

    return Observable.create { subscriber ->
        Observable.concatEager(listOfCalculations.map { calculation: Calculation ->
            doCalculation(calculation).subscribeOn(Schedulers.computation()) // function doCalculation returns an Observable with only one result
        }).subscribeBy(
            onNext = {
                results.add(it)
                subscriber.onNext(Pair("A calculation is ready", it))

            },
            onComplete = {
                subscriber.onNext(Pair("Finished: ${results.size}", findBestCalculation(results)) 
                subscriber.onComplete()
            },
            onError = {
                subscriber.onError(it)
            }
        )
    }
}

আরএক্সকোটলিনের সাথে পরিচিত নয় বা @Volatile, তবে এটি যদি একই সাথে বেশ কয়েকটি থ্রেড দ্বারা ডাকা হয় তবে কীভাবে এটি কাজ করবে? ফলাফল কি হবে?
eis

0

আমার অনুরূপ সমস্যা ছিল, আমার সাম্প্রতিক অনুসন্ধানপ্রোগ্রাইডার Aউথোরিটি থেকে সংরক্ষণ পরামর্শগুলি একীকরণ করার সময় বিশ্রাম কল থেকে অনুসন্ধান আইটেমগুলি আনতে হবে এবং সেগুলিকে একত্রিত তালিকার সাথে একত্রিত করতে হবে। আমি @ মাইডগটম সলিউশনটি ব্যবহার করার চেষ্টা করছিলাম, দুর্ভাগ্যক্রমে আরএক্সজাভাতে কোনও পর্যবেক্ষণযোগ্য নেই rom কিছু গবেষণা করার পরে আমি একটি সমাধান পেয়েছিলাম যা আমার পক্ষে কাজ করে।

 fun getSearchedResultsSuggestions(context : Context, query : String) : Single<ArrayList<ArrayList<SearchItem>>>
{
    val fetchedItems = ArrayList<Observable<ArrayList<SearchItem>>>(0)
    fetchedItems.add(fetchSearchSuggestions(context,query).toObservable())
    fetchedItems.add(getSearchResults(query).toObservable())

    return Observable.fromArray(fetchedItems)
        .flatMapIterable { data->data }
        .flatMap {task -> task.observeOn(Schedulers.io())}
        .toList()
        .map { ArrayList(it) }
}

আমি পর্যবেক্ষণের অ্যারে থেকে একটি পর্যবেক্ষণযোগ্য তৈরি করেছি যা ক্যোয়ারীর উপর নির্ভর করে ইন্টারনেট থেকে প্রস্তাব এবং ফলাফলের তালিকা রয়েছে। এর পরে আপনি কেবল ফ্ল্যাটম্যাপআইটিরেবলের সাথে সেই কাজগুলি সরিয়ে নিয়ে ফ্ল্যাটম্যাপ ব্যবহার করে চালাবেন, ফলাফলগুলিকে অ্যারেতে রাখুন, যা পরে একটি পুনর্ব্যবহারযোগ্য দৃশ্যে নিয়ে আসা যায়।


0

আপনি প্রকল্পের চুল্লী ব্যবহার করেন, তাহলে আপনি ব্যবহার করতে পারেন Mono.when

Mono.when(publisher1, publisher2)
.map(i-> {
    System.out.println("everything is done!");
    return i;
}).block()
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.