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

本文详细介绍了如何使用RxJS库实现点击事件触发时,从缓存中随机获取用户并展示的功能。通过事件流与缓存数据的结合,实现了用户列表的动态更新和展示。

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');
});

 

转载于:https://www.cnblogs.com/Answer1215/p/5260420.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值