7

मुझे अवलोकनों की एक पुनरावर्ती श्रृंखला के साथ कुछ परेशानी हो रही है।आरएक्सजेएस: अवलोकन और एकल पर्यवेक्षक की रिकर्सिव सूची

मैं RxJS, जो संस्करण 1.0.10621 में है, और, सबसे बुनियादी आरएक्स कार्यक्षमता शामिल हैं jQuery के लिए Rx के साथ संयोजन के रूप में साथ काम कर रहा हूँ।

मुझे अपनी समस्या के लिए एक उदाहरण परिदृश्य प्रस्तुत करने दें: मैं एक निश्चित कीवर्ड वाले ट्वीट्स/अपडेट के लिए Twitter search API (JSON प्रतिक्रिया) मतदान कर रहा हूं। प्रतिक्रिया में "refresh_url" भी शामिल है जिसे फॉलो-अप अनुरोध उत्पन्न करने के लिए उपयोग करना चाहिए। उस फॉलो-अप अनुरोध की प्रतिक्रिया में फिर से एक नया refresh_url, आदि शामिल होगा

Rx.jQuery मुझे ट्विटर खोज एपीआई को एक अवलोकन करने योग्य ईवेंट बनाने की अनुमति देता है, जो एक पर अगला बनाता है और फिर पूरा करता है। मैंने अभी तक जो प्रयास किया है, वह है कि अगले हैंडलर को refresh_url याद रखें और इसे अगले अनुरोध के लिए एक नए अवलोकन योग्य और संबंधित पर्यवेक्षक दोनों का उत्पादन करने के लिए पूर्ण हैंडलर में उपयोग करें। इस तरह, एक अवलोकन + पर्यवेक्षक जोड़ी अन्य अनिश्चित काल तक चलता है।

इस दृष्टिकोण के साथ समस्या है:

  1. अनुवर्ती नमूदार/पर्यवेक्षक पहले से ही जीवित हैं जब उनके पूर्ववर्तियों अभी तक का निपटारा नहीं किया गया है।

  2. मैं बुरा बहीखाता की बहुत सारी करने के लिए वर्तमान में रहने वाले पर्यवेक्षक, जिनमें से वास्तव में दो हो सकता है के लिए एक वैध संदर्भ बनाए रखने के लिए किया है। (एक में पूर्ण और दूसरा जीवन चक्र में कहीं और) यह संदर्भ, पर्यवेक्षक की सदस्यता समाप्त करने/निपटाने के लिए आवश्यक है। बहीखाता का एक विकल्प "अभी भी चल रहा है" के माध्यम से साइड इफेक्ट को लागू करना होगा - बूलियन, जैसा कि मैंने अपने उदाहरण में किया है।

उदाहरण कोड:

  running = true; 
      twitterUrl = "http://search.twitter.com/search.json"; 
      twitterQuery = "?rpp=10&q=" + encodeURIComponent(text); 
      twitterMaxId = 0; //actually twitter ignores its since_id parameter 

      newTweetObserver = function() { 
       return Rx.Observer.create(
         function (tweet) { 
          if (tweet.id > twitterMaxId) { 
           twitterMaxId = tweet.id; 
           displayTweet(tweet); 
          } 
         } 
        ); 
      } 

      createTwitterObserver = function() { 
       twitterObserver = Rx.Observer.create(
         function (response) { 
          if (response.textStatus == "success") { 
           var data = response.data; 
           if (data.error == undefined) { 
            twitterQuery = data.refresh_url; 
            var tweetObservable; 
            tweetObservable = Rx.Observable.fromArray(data.results.reverse()); 
            tweetObservable.subscribe(newTweetObserver()); 
           } 
          } 
         }, 
         function(error) { alert(error); }, 
         function() { 
          //create and listen to new observer that includes a delay 
          if (running) { 
           twitterObservable = $.getJSONPAsObservable(twitterUrl, twitterQuery).delay(3000); 
           twitterObservable.subscribe(createTwitterObserver()); 
          } 
         } 
        ); 
       return twitterObserver; 
      } 
      twitterObservable = $.getJSONPAsObservable(twitterUrl, twitterQuery); 
      twitterObservable.subscribe(createTwitterObserver()); 

ट्वीट्स के लिए अनुरोध से observables/पर्यवेक्षकों की दोहरी परत से धोखा न खाएं। मेरा उदाहरण मुख्य रूप से पहली परत के साथ चिंतित है: ट्विटर से डेटा का अनुरोध। यदि इस समस्या को हल करने में दूसरी परत (प्रतिक्रियाओं को ट्वीट्स में परिवर्तित करना) पहले के साथ एक हो सकता है, यह शानदार होगा; लेकिन मुझे लगता है कि यह एक पूरी तरह से अलग बात है। अभी के लिए।

इरिक मेजर मेरे लिए विस्तृत ऑपरेटर ने बताया (नीचे उदाहरण देखें), और एक विकल्प के रूप Join patterns का सुझाव दिया।

var ys = Observable.Expand 
(new[]{0}.ToObservable() // initial sequence 
        , i => (i == 10 ? Observable.Empty<int>() // terminate 
     : new[]{i+1}.ToObservable() // recurse 
) 
); 

ys.ToArray().Select(a => string.Join(",", a)).DumpLive(); 

यह LINQPad में कॉपी-पेस्टेबल होना चाहिए। यह सिंगलटन अवलोकन को मानता है और एक अंतिम पर्यवेक्षक का उत्पादन करता है।

तो मेरे सवाल है: मैं RxJS में विस्तार चाल सबसे अच्छा कर सकते हैं कैसे?

संपादित करें:
विस्तार ऑपरेटर को शायद this thread में दिखाया गया अनुसार लागू किया जा सकता है। लेकिन किसी को generators की आवश्यकता होगी (और मेरे पास केवल JS < 1.6 है)।
दुर्भाग्य से RxJS 2.0.20304-beta विस्तार विधि को लागू नहीं करता है।

+2

मैं निष्कर्ष है कि इस समस्या का समाधान वास्तव में है [ऑपरेटर का विस्तार करें] (http://social.msdn.microsoft.com/Forums/da-DK/rx/thread/2746e373- के लिए आए हैं bf43-4381-834c-8cc182704ae9) जिसे अभी तक संस्करण 2.0.20304-बीटा तक आरएक्सजेएस में लागू नहीं किया गया है। – derabbink

+1

विस्तार वही है जो आपको चाहिए। मुझे एहसास है कि यह पोस्ट पुराना है, लेकिन आरएक्स के अपने संस्करण में आरएक्स के भविष्य संस्करण से आपको आवश्यक ऑपरेटरों को बस ट्रांसप्लेंट करना संभव है। इसमें कुछ हेरफेर की आवश्यकता हो सकती है, लेकिन कोड बेस को पूर्व-v1 से काफी नहीं बदला गया है। –

+0

इसके अलावा, आरएक्स (जहां संभव हो) को अपग्रेड करना एक अच्छा निर्णय है। नवीनतम संस्करणों में कई बग फिक्स और सुधार हैं। –

उत्तर

4

तो मैं आपकी समस्या को थोड़ा अलग से तुमने किया था और कुछ स्वतंत्रता है कि आप आसान हल कर सकते हैं लेने के हल करने के लिए प्रयास करने के लिए जा रहा हूँ।

तो 1 बात मैं नहीं बता सकता है कि आप निम्नलिखित का प्रयास कर रहे है कदम

  • वर्तमान पर्यवेक्षक onNext, पहले ट्वीट सूची, जो अगले यूआरएल
  • एक बार सूची ट्वीट प्राप्त होता है जाओ और मिल ट्वीट्स के अगले सेट
    • क्या यह अनिश्चित काल के लिए

या क्या कोई उपयोगकर्ता क्रिया है (नीचे/नीचे स्क्रॉलिंग करें)। किसी भी तरह से, यह वास्तव में एक ही समस्या है। हालांकि मैं आपकी समस्या को गलत तरीके से पढ़ रहा हूं। इसके लिए यहां जवाब है।

function getMyTweets(headUrl) { 
    return Rx.Observable.create(function(observer) { 

     innerRequest(headUrl); 
     function innerRequest(url) { 
      var next = ''; 

      // Some magic get ajax function 
      Rx.get(url).subscribe(function(res) { 
       observer.onNext(res); 
       next = res.refresh_url; 
      }, 
      function() { 
       // Some sweet handling code 
       // Perhaps get head? 
      }, 
      function() { 
       innerRequest(next); 
      }); 
     } 
    }); 
} 

यह वह उत्तर नहीं हो सकता है जिसे आप पूछ रहे थे। यदि नहीं, क्षमा करें!


संपादित करें: अपने कोड को देखने के बाद, ऐसा लगता है कि आप परिणाम को सरणी के रूप में लेना चाहते हैं और इसे देखना चाहते हैं।

// From the results perform a select then a merge (if ordering does not matter). 
getMyTweets('url') 
    .selectMany(function(data) { 
     return Rx.Observable.fromArray(data.results.reverse()); 
    }); 

// Ensures ordering 
getMyTweets('url') 
    .select(function(data) { 
     return Rx.Observable.fromArray(data.results.reverse()); 
    }) 
    .concat(); 
संबंधित मुद्दे