Skip to content

Commit

Permalink
add study cases:merge,combineLast
Browse files Browse the repository at this point in the history
  • Loading branch information
wbpmrck committed May 25, 2017
1 parent 41f99a0 commit 265fb71
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 34 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ study cases of Rxjs library

- Combination Operators
- combineAll
- combineLatest
- [combineLatest](./study/operators/combineLatest.html)
- [concat](./study/operators/concat.html)
- [concatAll](./study/operators/concatAll.html)
- exhaust
Expand Down
106 changes: 106 additions & 0 deletions study/operators/combineLatest.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>operator:combineLatest(较为复杂,需要认真看下面说明)</title>

<link rel="stylesheet" href="../reset.css">
<link rel="stylesheet" href="../share.css">
<script src="../Rx.min.js"></script>
</head>
<body>

<h1 class="operator-name">combineLatest</h1>

<ul class="operator-params">
参数列表:
<li>
<span class="operator-params-name">observables</span>
<span class="operator-params-type">ObservableInput,...ObservableInput 或者 [...ObservableInput]</span>
<span class="operator-params-desc">1个或者多个Observable(也可以是observable数组),他们会被用来与source进行combine</span>
</li>
<li>
<span class="operator-params-name">project</span>
<span class="operator-params-type">function(val1,val2,...) : T</span>
<span class="operator-params-desc">(可选)用于对参与combine的数据进行操作,并返回要发射的数据,如果不填,则默认返回[val1,val2,...]。</span>
</li>
<li>
<span class="operator-params-name">scheduler</span>
<span class="operator-params-type">Scheduler</span>
<span class="operator-params-desc">调度器</span>
</li>


</ul>
返回值:<h2 class="operator-ret"> Observable</h2>

<hr>
<h1>珠宝图:</h1>
<div class="marble-box">
<img src="combineLatest.png" alt="" class="operator-marble">
</div>
<hr>
<h1>功能说明:</h1>
<ul class="desc">
<li>combineLatest 会订阅传入的所有observables.</li>
<li>combineLatest内部使用一个数组保存所有observables最近一次发出的值。</li>
<li>如果传入空数组,combineLatest会立刻complete。</li>
<li>combineLatest 会等待每一个observable至少emit一个值,然后才开始输出。这就意味着,如果存在一个source在其他source发射value之前发射了多个值
那只有最后一个有效,其他的都被覆盖了</li>
<li>如果有一个source没有emit任何value就complete了,那么整个combine也会complete</li>
<li>如果右一个source既没有emit任何value,也没有complete,那么整个combine也会一直等,什么也不emit.因为他必须等所有source至少emit一个值</li>
<li>一旦所有source都发出过value,那么combine会等所有source都complete才complete。此时哪怕有若干source已经complete,但是他们的最后一次emit的值仍然会被使用</li>
<li>任何一个source发出error,整个combine发出Error,并且退订其他所有source</li>
<li></li>
</ul>
<hr>
<h1>备注事项:</h1>
<ul class="notice">
<li>combineLatest 一定会等到所有source都至少发出1个值</li>
</ul>

<div class="demo">
<span>点击不同按钮查看不同demo 代码效果</span>
<button onclick="demo1();">demo1</button>
<button onclick="demo2();">demo2</button>
<button onclick="demo3();">demo3</button>
</div>

<script>
function demo1(){
console.log("combineLatest:2个timer刚好错开0.5s,他们的值交替增加。不提供project function,会直接输出[value1,value2]")

const firstTimer = Rx.Observable.timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
const secondTimer = Rx.Observable.timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
const combinedTimers = Rx.Observable.combineLatest(firstTimer, secondTimer);
combinedTimers.subscribe(value => console.log(value));
// Logs
// [0, 0] after 0.5s
// [1, 0] after 1s
// [1, 1] after 1.5s
// [2, 1] after 2s
}
function demo2() {

console.log("combineLatest:2个timer刚好错开0.5s,他们的值交替增加。提供project function,对他们的值进行累加(console中第三个位置数字)")

const firstTimer = Rx.Observable.timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
const secondTimer = Rx.Observable.timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
const combinedTimers = Rx.Observable.combineLatest(firstTimer, secondTimer,(val1,val2)=>[val1,val2,val1+val2]);
combinedTimers.subscribe(value => console.log(value));
}
function demo3() {

console.log("combineLatest:在2个timer上添加了一个鼠标点击事件,所以必须至少点击一次图片之后,才能看到输出.并且过程中点击图片,会立刻输出一个值,此时其他source都是用最后一次的值来计算")

const sourceOfMouse = Rx.Observable.fromEvent(document,"click").filter((evt)=>evt.target.tagName==='IMG');
const firstTimer = Rx.Observable.timer(0, 1000); // emit 0, 1, 2... after every second, starting from now
const secondTimer = Rx.Observable.timer(500, 1000); // emit 0, 1, 2... after every second, starting 0,5s from now
const combinedTimers = Rx.Observable.combineLatest(firstTimer, secondTimer,sourceOfMouse,(val1,val2,evt)=>[val1,val2,evt,val1+val2]);
combinedTimers.subscribe(value => console.log(value));
}
</script>


</body>
</html>
Binary file added study/operators/combineLatest.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 29 additions & 33 deletions study/operators/merge.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,17 @@ <h1 class="operator-name">merge</h1>
<li>
<span class="operator-params-name">other</span>
<span class="operator-params-type">...ObservableInput</span>
<span class="operator-params-desc">1个或者多个Observable,他的值会被接在source的值之后发送</span>
<span class="operator-params-desc">1个或者多个Observable,他的值会被订阅,和source的值一起,各自发送</span>
</li>
<li>
<span class="operator-params-name">concurrent</span>
<span class="operator-params-type">number</span>
<span class="operator-params-desc">(可选)merge可以同时订阅的source数量,默认是正无穷大。</span>
</li>
<li>
<span class="operator-params-name">scheduler</span>
<span class="operator-params-type">Scheduler</span>
<span class="operator-params-desc">调度器</span>
</li>


Expand All @@ -32,12 +42,14 @@ <h1>珠宝图:</h1>
<hr>
<h1>功能说明:</h1>
<ul class="desc">
<li>merge 订阅Source发射出的每一个Observable,并且把内部Observable的值转发出来。他必须等待前一个内部Observable的complete之后才会订阅下一个</li>
<li>merge 订阅Source以及其他输入的所有值,然后发出。如果不设置concurrent,则感觉和同时订阅多个source效果一样</li>
</ul>
<hr>
<h1>备注事项:</h1>
<ul class="notice">
<li>必须等到前一个inner observable发生complete之后,concatAll才会订阅下一个source返回的Observable</li>
<li>complete 的发出:必须等到所有输入都complete</li>
<li>error 的发出:任何一个source发生error,merge都会error</li>
<li>merge也可以作为static方法使用</li>
</ul>

<div class="demo">
Expand All @@ -48,51 +60,35 @@ <h1>备注事项:</h1>

<script>
function demo1(){
console.log("merge:3个inner observable通过计时器发射数据,先慢后快。")
var obs1 = Rx.Observable.interval(1000).take(5);
var obs2 = Rx.Observable.interval(500).take(4);
var obs3 = Rx.Observable.interval(100).take(3);

var source = obs1.merge(obs2, obs3);
console.log("merge:2个source,1个是页面点击事件流,一个是计时器")
var clicks = Rx.Observable.fromEvent(document, 'click');
var timer = Rx.Observable.interval(1000);
var clicksOrTimer = clicks.merge(timer);
clicksOrTimer.subscribe(x => console.log(x));
}
function demo2() {

var example = source.merge();
console.log("merge:2个计时器,都complete才会complete")
var source = Rx.Observable.interval(1500).take(3);
var source2 = Rx.Observable.interval(100).take(6);
var example = source.merge(source2);

example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// 3
// 4
// 0
// 1
// 2
// 3
// 0
// 1
// 3
// 2
// 4
// 5
// complete
}
function demo2() {

console.log("merge:和demo1一样,使用concat静态方法,合并3个inner observable通过计时器发射数据,先慢后快。")
var obs1 = Rx.Observable.interval(1000).take(5);
var obs2 = Rx.Observable.interval(500).take(4);
var obs3 = Rx.Observable.interval(100).take(3);

var source = Rx.Observable.merge(obs1,obs2, obs3);

var example = source.merge();

example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
}
</script>


Expand Down
Binary file added study/operators/merge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 265fb71

Please sign in to comment.