[RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()

Posted Answer1215

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()相关的知识,希望对你有一定的参考价值。

技术分享

So now we want to replace one user when we click the ‘x‘ button. 

 

To do that, we want:

1. Get the cached network data for generating the userList.

2. Then get a random user from the cached data.

3. Showing the user in the list.

 

We have the function to create suggestion user:

function createSuggestionStream(responseStream, closeClickStream) {
  return responseStream.map(getRandomUser)
    .startWith(null)
    .merge(refreshClickStream.map(ev => null))
}

It contains the ‘responseStream‘ which contains the cached data we need.

So, the code would somehow like this:

  var close1Clicks = Rx.Observable.fromEvent(closeButton1, ‘click‘);
  close1Clicks.withLatestFrom(responseStream, (clickEv, cachedData) => {
    return getRandomUser(cachedData);
  });

When the closeClickStream happens, it will fetch the cached data and send userList to getRandomUser() function to pick user.

 

Now, we can merge this stream with responseStream:

function createSuggestionStream(responseStream, closeClickStream) {
  return responseStream.map(getRandomUser)
    .startWith(null)
    .merge(refreshClickStream.map(ev => null))
    .merge(
      closeClickStream.withLatestFrom(responseStream, 
                                  (clickEv, cachedData) => getRandomUser(cachedData))
    );
}

 

-----------

var refreshButton = document.querySelector(‘.refresh‘);
var closeButton1 = document.querySelector(‘.close1‘);
var closeButton2 = document.querySelector(‘.close2‘);
var closeButton3 = document.querySelector(‘.close3‘);

var refreshClickStream = Rx.Observable.fromEvent(refreshButton, ‘click‘);
var close1Clicks = Rx.Observable.fromEvent(closeButton1, ‘click‘);
var close2Clicks = Rx.Observable.fromEvent(closeButton2, ‘click‘);
var close3Clicks = Rx.Observable.fromEvent(closeButton3, ‘click‘);

var startupRequestStream = Rx.Observable.just(‘https://api.github.com/users‘);

var requestOnRefreshStream = refreshClickStream
  .map(ev => {
    var randomOffset = Math.floor(Math.random()*500);
    return ‘https://api.github.com/users?since=‘ + randomOffset;
  });

var requestStream = startupRequestStream.merge(requestOnRefreshStream);

var responseStream = requestStream
  .flatMap(requestUrl =>
    Rx.Observable.fromPromise(jQuery.getJSON(requestUrl))
  )
  .shareReplay(1);

// refreshClickStream: -------f------------->
// requestStream:      r------r------------->
// responseStream:     ---R-------R--------->
// closeClickStream:   ---------------x----->
// suggestion1Stream:  N--u---N---u---u----->

function getRandomUser(listUsers) {
  return listUsers[Math.floor(Math.random()*listUsers.length)];
}

function createSuggestionStream(responseStream, closeClickStream) {
  return responseStream.map(getRandomUser)
    .startWith(null)
    .merge(refreshClickStream.map(ev => null))
    .merge(
       closeClickStream.withLatestFrom(responseStream, 
                                  (clickEv, cachedData) => getRandomUser(cachedData))
    );
}

var suggestion1Stream = createSuggestionStream(responseStream, close1Clicks);
var suggestion2Stream = createSuggestionStream(responseStream, close2Clicks);
var suggestion3Stream = createSuggestionStream(responseStream, close3Clicks);

// Rendering ---------------------------------------------------
function renderSuggestion(suggestedUser, selector) {
  var suggestionEl = document.querySelector(selector);
  if (suggestedUser === null) {
    suggestionEl.style.visibility = ‘hidden‘;
  } else {
    suggestionEl.style.visibility = ‘visible‘;
    var usernameEl = suggestionEl.querySelector(‘.username‘);
    usernameEl.href = suggestedUser.html_url;
    usernameEl.textContent = suggestedUser.login;
    var imgEl = suggestionEl.querySelector(‘img‘);
    imgEl.src = "";
    imgEl.src = suggestedUser.avatar_url;
  }
}

suggestion1Stream.subscribe(user => {
  renderSuggestion(user, ‘.suggestion1‘);
});

suggestion2Stream.subscribe(user => {
  renderSuggestion(user, ‘.suggestion2‘);
});

suggestion3Stream.subscribe(user => {
  renderSuggestion(user, ‘.suggestion3‘);
});

 

以上是关于[RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()的主要内容,如果未能解决你的问题,请参考以下文章

[RxJS] Reactive Programming - Using cached network data with RxJS -- withLatestFrom()

[RxJS] Reactive Programming - Sharing network requests with shareReplay()

[RxJS] Reactive Programming - New requests from refresh clicks -- merge()

Reactive-Extensions / RxJS和ReactiveX / rxjs之间有什么区别

全面拥抱 Reactivity: RxJS, RSocket & Svelte

RxJS的基础