उस फ़ंक्शन से मान कैसे लौटाया जा सकता है जिसके अंदर अवलोकन योग्य सदस्यता है?


98

मुझे पता नहीं है कि ऑब्जर्वेबल से मूल्य कैसे निकाला जाए कि फ़ंक्शन द्वारा वापस लौटाया जाए जिसमें ऑब्जर्वेबल मौजूद है। मुझे इसे वापस करने के लिए सिर्फ एक मूल्य की आवश्यकता है, और कुछ नहीं।

वर्तमान संस्करण जो काम करता है

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            console.log(data)
        }
    )
}
getValueFromObservable()

मुझे यह काम करने की आवश्यकता है, मान वापस करने के लिए कार्य करें, और फिर:

function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            return data
        }
    )
}
console.log(getValueFromObservable())

मुझसे यहां क्या गलत हो रहा है?


2
आपको एक ऑब्जर्वेबल / प्रॉमिस लौटाना चाहिए और डेटा को तब पास करना चाहिए जब आपका
ऑब्जर्वेबल

2
क्या आप इसके लिए कुछ सरल कोड डाल सकते हैं?
टेड्डी

6
आप जो हासिल करने की कोशिश कर रहे हैं, वह एक एंटी-पैटर्न है: आप एक async कार्य को "सिंक्रनाइज़" करने की कोशिश कर रहे हैं। इस तरह से वेधशालाएं काम करने वाली नहीं हैं। संक्षेप में, ज्यादातर मामलों में, इनपुट के रूप में एक ऑब्जर्वेबल होने वाले एक फ़ंक्शन को भी एक अवलोकन योग्य लौटना चाहिए - या कुछ भी वापस नहीं करना चाहिए। और जब आपको आउटपुट के साथ कुछ करने की आवश्यकता हो, तो उसे सब्सक्राइब करें। इस स्थिति में यदि आप डेटा को सांत्वना देना चाहते हैं, तो बस इसे अंदर करेंsubscribe
Can Nguyen

1
मैं समझ गया आप सब ने कहा। मैं सिर्फ कंसोल लॉग को डेमो के रूप में उपयोग कर रहा हूं, मैं उस डेटा का आगे उपयोग करूंगा, यही कारण है कि मुझे अवलोकन योग्य के बाहर कंसोल लॉग की आवश्यकता है। इस फंक्शन में वह फंक्शन है जो जब आप ऑब्जर्वेबल को सब्सक्राइब कर सकते हैं, तो उस फंक्शन में डेटा, अनसब्सक्राइब और रिटर्न डेटा प्राप्त कर सकते हैं ताकि मैं उस डेटा को आगे इस्तेमाल कर सकूं। मुझे पता है कि यह पैटर्न-विरोधी है, लेकिन मुझे काम करने की आवश्यकता है। किसी भी मदद की सराहना की है। वर्तमान में मेरा समाधान काम करता है, लेकिन मैं इसके बारे में बहुत ज्यादा आश्वस्त नहीं हूं।
टेडी

4
कृपया ध्यान दें! 'समाधान' अनुभाग से कोड बिल्कुल गलत है। इसका उपयोग न करें! यह तभी काम करेगा जब यह अनुभाग .store.subscribe ((data: any) => {output = data}) .unsubscribe () वापसी तक समाप्त हो जाएगा। अन्यथा यह अपरिभाषित होकर लौटेगा।
रोडियन गोलोवुस्किन

जवाबों:


58

EDIT: RXJS के अधिक हाल के संस्करणों में पाइप के काम करने के तरीके में परिवर्तन को प्रतिबिंबित करने के लिए अद्यतन कोड। सभी ऑपरेटर (मेरे उदाहरण में लें) अब पाइप () ऑपरेटर में लिपटे हुए हैं।

मुझे एहसास है कि यह प्रश्न काफी समय पहले था और आपके पास निश्चित रूप से अब तक एक उचित समाधान है, लेकिन जो कोई भी इस की तलाश कर रहा है, मैं उसे async पैटर्न रखने के लिए एक वादा के साथ हल करने का सुझाव दूंगा।

एक अधिक वर्बोज़ संस्करण एक नया वादा बना रहा होगा:

function getValueFromObservable() {
    return new Promise(resolve=>{
        this.store.pipe(
           take(1) //useful if you need the data once and don't want to manually cancel the subscription again
         )
         .subscribe(
            (data:any) => {
                console.log(data);
                resolve(data);
         })
    })
}

प्राप्त करने के अंत में आपको कुछ इस तरह से हल करने के वादे के लिए "प्रतीक्षा" होगी:

getValueFromObservable()
   .then((data:any)=>{
   //... continue with anything depending on "data" after the Promise has resolved
})

RxJS '.toPromise () के बजाय एक स्लिमर समाधान का उपयोग किया जाएगा:

function getValueFromObservable() {
    return this.store.pipe(take(1))
       .toPromise()   
}

प्राप्त करने वाला पक्ष पाठ्यक्रम के ऊपर जैसा होता है।


आपके getValueFromObservableफ़ंक्शन का रिटर्न प्रकार क्या है ?
hardywang

स्टोर डेटा जो भी प्रकार है, उसके साथ एक वादा होना चाहिए। उदाहरण के लिए वादा <StoreType>
jparg

4
आप अभी भी एक वादा वापस कर रहे हैं जिसे हल करने की आवश्यकता है और सीधे मूल्य वापस नहीं करना है।
रोज

1
प्रॉपर्टी 'टेक' का प्रकार 'ऑब्जर्वेबल <>' पर मौजूद नहीं है
मेमो

1
@Memmo .pipe कोशिश (ले (1)) के बजाय
Thibault

20

यह उपयोग करने का बिल्कुल सही विचार नहीं है Observable

घटक में आपको वर्ग सदस्य घोषित करना होगा जो एक वस्तु धारण करेगा (कुछ आप अपने घटक में उपयोग करने जा रहे हैं)

export class MyComponent {
  name: string = "";
}

फिर एक Serviceतुम वापस आ जाएगा Observable:

getValueFromObservable():Observable<string> {
    return this.store.map(res => res.json());
}

Component इसके लिए एक मान प्राप्त करने में सक्षम होने के लिए खुद को तैयार करना चाहिए:

OnInit(){
  this.yourServiceName.getValueFromObservable()
    .subscribe(res => this.name = res.name)
}

आपको Observableएक वैरिएबल से एक मान असाइन करना होगा :

और आपका खाका परिवर्तनशील होगा name:

<div> {{ name }} </div>

उपयोग करने का एक और तरीका पाइप http://briantroncone.com/?p=623 केObservable माध्यम से हैasync

नोट : यदि यह वह नहीं है जो आप पूछ रहे हैं, तो कृपया अधिक विवरण के साथ अपने प्रश्न को अपडेट करें


खैर काफी नहीं। समस्या यह है कि डेटा को ऑब्जर्वेबल के अंदर कैद किया जाता है और मैं बस इसे लॉग इन कंसोल कर सकता हूं। मैं उस वैल्यू और कंसोल.लॉग या जो कुछ भी अलग फ़ाइल से फ़ंक्शन को कॉल करके वापस करना चाहता हूं जिसमें वह रहता है।
टेडी

आंद्रेई ने बताया nameकि घटक के nameचर को निर्दिष्ट करके कॉलबैक के बाहर उपलब्ध कैसे करें । nameआपके मामले में समकालिक रूप से लौटना संभव नहीं है ।
मैट

@ मैट: मैं इसे इस Oninitतरह से उपयोग नहीं कर सकता , क्या होगा अगर मुझे स्पष्ट रूप से वापस जाने की जरूरत है, मेरा कॉलिंग कोड इस तरह दिखता है this.actions$.ofType(SearchActions.SEARCH_MULTIPLE_NEW_QUERY).map(toPayload).fnWithMultipleAsyncReturns()
ishandutta2007

@ ishandutta2007 अरे वहाँ। आप अपने मुद्दे के संबंध में SO पर एक नया प्रश्न बनाना बेहतर समझते हैं।
मैट

@Matt: बनाया गया है, यदि आप एक नज़र रखना चाहते हैं ( stackoverflow.com/questions/43381922/… )
ishandutta2007

7

यदि आप उसी ऑब्जर्वेबल को प्री-सब्सक्राइब करना चाहते हैं जो वापस आ जाएगा, तो बस उपयोग करें

।करना():

function getValueFromObservable() {
    return this.store.do(
        (data:any) => {
            console.log("Line 1: " +data);
        }
    );
}

getValueFromObservable().subscribe(
        (data:any) => {
            console.log("Line 2: " +data)
        }
    );

3
आप अन्य ऑपरेटरों का भी उपयोग कर सकते हैं जैसे .map(data => data)कि वही काम करता है और फिर परिणाम की उम्मीद होने पर सदस्यता लें
ashok_khuman

मैं ashok_khuman से सहमत हूं। यहाँ गाइड है angular.io/guide/pipes
आर्मंडो

यह एक अच्छा जवाब हो सकता है, लेकिन वास्तव में आपने इसके बारे में कुछ भी नहीं बताया, यह एक बुरा जवाब है। "पूर्व-सदस्यता" का क्या अर्थ है? और क्या इसे थ्रेड ओपनर से सवाल हल करना चाहिए?
फ्लोरियन लेटेजब

ध्यान दें कि RxJS 6 doमें अब कॉल किया गया है tapऔर आपको इसे एक पाइप में उपयोग करना होगा। यह भी ध्यान दें कि tapविभिन्न संचालकों के लिए कई मापदंडों को लेता है जैसे कि next, completeऔर error
सिमोन_विवर

7

समस्या यह है कि डेटा को ऑब्जर्वेबल के अंदर कैद किया जाता है और मैं बस इसे लॉग इन कंसोल कर सकता हूं। मैं उस वैल्यू और कंसोल.लॉग या जो कुछ भी अलग फ़ाइल से फ़ंक्शन को कॉल करके वापस करना चाहता हूं जिसमें वह रहता है।

ऐसा लगता है कि आप एक अवलोकन के अंदर "वर्तमान मूल्य" पाने वाले की तलाश कर रहे हैं, जब वह उत्सर्जन करता है और उत्सर्जन के बाद।

Subjectऔर Observableऐसी बात नहीं है। जब कोई मूल्य उत्सर्जित होता है, तो वह अपने ग्राहकों को दिया Observableजाता है और इसके साथ किया जाता है।

आप उपयोग कर सकते हैं BehaviorSubjectजो अंतिम उत्सर्जित मूल्य को संग्रहीत करता है और इसे तुरंत नए ग्राहकों के लिए उत्सर्जित करता है।

यह भी एक getValue() वर्तमान मूल्य प्राप्त करने के लिए विधि ;

आगे की पढाई:

RxJS व्यवहार व्यवहार

RxJS विषय या अवलोकन का वर्तमान मूल्य कैसे प्राप्त करें?


2

अवलोकन योग्य मूल्यों को किसी भी स्थान से प्राप्त किया जा सकता है। स्रोत अनुक्रम को पहले एक विशेष पर्यवेक्षक पर धकेल दिया जाता है जो कहीं और उत्सर्जन करने में सक्षम होता है। यह रिएक्टिव एक्सटेंशन्स (RxJS) से सब्जेक्ट क्लास के साथ हासिल किया जाता है ।

var subject = new Rx.AsyncSubject();  // store-last-value method

प्रेक्षक पर स्टोर वैल्यू ।

subject.next(value); // store value
subject.complete(); // publish only when sequence is completed

मान को कहीं और से प्राप्त करने के लिए, पर्यवेक्षक की सदस्यता लें जैसे:

subject.subscribe({
  next: (response) => {
      //do stuff. The property name "response" references the value
  }
});

विषय वेधशाला और प्रेक्षक दोनों हैं। अन्य विषय प्रकार हैं अन्य उपयोग परिदृश्यों के लिए इस तरह के BehaviourSubject और ReplaySubject के रूप में।

RxJS आयात करना न भूलें।

var Rx = require('rxjs');

1

हालांकि पिछले उत्तर फैशन में काम कर सकते हैं, मुझे लगता है कि यदि आप वेधशालाओं का उपयोग जारी रखना चाहते हैं तो BehaviorSubject का उपयोग करना सही तरीका है।

उदाहरण:

    this.store.subscribe(
        (data:any) => {
            myService.myBehaviorSubject.next(data)
        }
    )

सेवा में:

let myBehaviorSubject = new BehaviorSubjet(value);

घटक में:

this.myService.myBehaviorSubject.subscribe(data => this.myData = data)

आशा है कि ये आपकी मदद करेगा!


0

उदाहरण के लिए यह मेरा html टेम्पलेट है:

<select class="custom-select d-block w-100" id="genre" name="genre"
                  [(ngModel)]="film.genre"
                  #genreInput="ngModel"
                  required>
            <option value="">Choose...</option>
            <option *ngFor="let genre of genres;" [value]="genre.value">{{genre.name}}</option>
          </select>

यह वह क्षेत्र है जो मेरे घटक से टेम्पलेट के साथ जुड़ा हुआ है:

  // Genres of films like action or drama that will populate dropdown list.
  genres: Genre[];

मैं गतिशील रूप से सर्वर से फिल्मों की शैलियों को लाता हूं। मेरे द्वारा बनाए गए सर्वर के साथ संवाद करने के लिएFilmService

यह वह विधि है जो सर्वर से संवाद करती है:

 fetchGenres(): Observable<Genre[]> {
    return this.client.get(WebUtils.RESOURCE_HOST_API + 'film' + '/genre') as Observable<Genre[]>;
  }

यह तरीका Observable<Genre[]>कुछ ऐसा क्यों नहीं लौटाता है Genre[]?

जावास्क्रिप्ट है asyncऔर यह एक महंगी प्रक्रिया के बाद मूल्य वापस करने के लिए एक विधि की प्रतीक्षा नहीं करता है। महंगी के साथ मेरा मतलब एक ऐसी प्रक्रिया है जो मूल्य वापस करने के लिए एक समय लेती है। जैसे सर्वर से डेटा लाना। इसलिए आपको ऑब्जर्वेबल के संदर्भ को वापस करना होगा और उसकी सदस्यता लेनी होगी।

मेरे घटक में उदाहरण के लिए:

ngOnInit() {
    this.filmService.fetchGenres().subscribe(
      val => this.genres = val
    );
  }

0
function getValueFromObservable() {
    this.store.subscribe(
        (data:any) => {
            return data
        }
    )
}
console.log(getValueFromObservable())

उपरोक्त मामले में कंसोल.लॉग वादा से पहले चलता है ताकि कोई मूल्य प्रदर्शित न हो, इसे निम्नलिखित में बदलें

function getValueFromObservable() {
    return this.store
}

getValueFromObservable()
 .subscribe((data: any) => {
    // do something here with data
    console.log(data);
});

अन्य समाधान तब होता है जब आपको ऑपरेटर के उपयोग योग्य अवलोकन वापस करने और फ़ंक्शन की सदस्यता लेने के लिए getValueFromObservable के अंदर डेटा की आवश्यकता होती है।

 function getValueFromObservable() {
        return this.store.subscribe((data: any) => {
            // do something with data here
            console.log(data);
            //return again observable.
            return of(data);
       })
    }

    getValueFromObservable()
     .subscribe((data: any) => {
        // do something here with data
        console.log(data);
    });

0

जावास्क्रिप्ट की एकल-पिरोया, अतुल्यकालिक, वादा-उन्मुख, प्रतिक्रियाशील-ट्रेंडिंग दुनिया में async/awaitअनिवार्य शैली प्रोग्रामर का सबसे अच्छा दोस्त है:

(async()=>{

    const store = of("someValue");
    function getValueFromObservable () {
        return store.toPromise();
    }
    console.log(await getValueFromObservable())

})();

और मामले storeमें कई मूल्यों का एक क्रम है:

  const aiFrom = require('ix/asynciterable').from;
  (async function() {

     const store = from(["someValue","someOtherValue"]);
     function getValuesFromObservable () {
        return aiFrom(store);
     }
     for await (let num of getValuesFromObservable()) {
       console.log(num);
     }
  })();

डेटा सरणी के मामले में मैं अतुल्यकालिकता का उपयोग क्यों करूंगा?
जनोस विन्सेलर

@JanosVinceller कोड के अन्य भागों पर ध्यान केंद्रित करने के लिए यह केवल एक उदाहरण है। आप from(["someValue","someOtherValue"])अपनी पसंद के एक अवलोकन से बदल सकते हैं जो एक से अधिक मूल्य का उत्सर्जन करता है। मुझे लगता है, यह उपयोग करने के लिए अधिक उपयुक्त हो सकता है interval(1000)
Marinos An

0

सभ्य तरीका यह होगा कि किसी फ़ंक्शन से ऑब्जर्वेबल को लौटाया जाए और जहां भी आवश्यक हो, उसकी सदस्यता लें, क्योंकि वे ऑब्जर्बल्स आलसी हैं, वे सब्सक्राइब होने पर ही मूल्यों का उत्सर्जन शुरू कर देंगे।

यहां मेरे पास एक और दिलचस्प घटना संचालित समाधान है, जिसे मैं शुरू में साथ खेलता था। नोडज के " घटनाओं " मॉड्यूल का उपयोग करके निम्नलिखित उदाहरण यह करता है । आप इसे अन्य चौखटों के साथ उपयोग कर सकते हैं जहाँ समान मॉड्यूल मौजूद है ( नोट : प्रयुक्त मॉड्यूल के आधार पर सिंटैक्स और शैली बदल सकती है)।

var from =require("rxjs").from;
var map = require("rxjs/operators").map;
var EventEmitter = require("events");

function process(event) {
    from([1,2,3]).pipe(
        map(val => `The number is:: ${val}`)
    ).subscribe((data) => {
       event.emit("Event1", data); //emit value received in subscribe to the "Event1" listener
    });
}

function main() {
   class Emitter extends EventEmitter{};
    var event = new Emitter(); //creating an event
    event.on("Event1", (data)=>{ //listening to the event of name "Event1" and callback to log returned result
        console.log(data); //here log, print, play with the data you receive
    });
    process(event); //pass the event to the function which returns observable.
}

main(); //invoke main function

यह केवल एक विचार को प्रदर्शित करने के लिए एक उदाहरण है जहां हम अलग-अलग स्थानों से डेटा को उत्सर्जित करने और सुनने की विधि से पारित कर सकते हैं। इसे ईवेंट-चालित कोड के रूप में भी जाना जाता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.