RawRxJS筆記

*不是我沒學(xué)弧腥,我只是懶得不想把Raw筆記轉(zhuǎn)碼了而已。~~懶得要死~~

注:本文學(xué)習(xí)環(huán)境為RxJs5.x版本革半,目前使用環(huán)境為RxJs6砂蔽,故部分聲明代碼不同

例如:大部分operator將不需要前置的Rx.Observable,直接調(diào)用即可署惯。

分割線-------------------------------------------------------------------------------------------------------------------------------------------------------------------

Observable可以同時(shí)處理同步與異步傳來的信息

var observable = Rx.Observable? ? // 1.創(chuàng)建一個(gè)observable對象左驾,新版應(yīng)改為直接使用Observable?

? ? .create(function(observer) {

? ? ? ? observer.next('Jerry'); // 同步部分

? ? ? ? observer.next('Anna');?

? ? ? ? setTimeout(() => {? ? ? // 異步部分

? ? ? ? ? ? observer.next('RxJS 30 days!');

observer.complete();? //停止observable,此后部分不會(huì)被顯示极谊。

observer.next("not work");

? ? ? ? }, 30)

? ? })

console.log('start');

observable.subscribe(function(value) {? // 2.訂閱這個(gè)observable對象诡右,并為其設(shè)置觀察者方法。

? ? console.log(value);

});

console.log('end');

輸出:

start

Jerry

Anna

end

RxJS 30 days!

對于subscribe方法來說轻猖,可以為其設(shè)定針對不同情況的不同處理帆吻,例如針對complete與異常拋出

var observer = {

next: function(value) {? ? ? //.next()走這里

console.log(value);

},

error: function(error) {? ? ? // 出現(xiàn)異常走這里

console.log('Error: ', error)

},

complete: function() {? ? ? ? //.complete()走這里

console.log('complete')

}

}

observable.subscribe(observer)? ? // 而后進(jìn)行訂閱

以上可以簡化為傳三個(gè)function參數(shù):

observable.subscribe(

? ? v => { console.log(v); },

? ? e => { console.log('Error: ', e); },

? ? () => { console.log('complete') }

)

訂閱函數(shù)subscribe()具有自己的返回值,是一個(gè)subscription對象

該對象可以用來停止某些不會(huì)complete()的訂閱過程咙边,即unsubscribe();

observable的常用creation operator

這些操作符都是用來創(chuàng)建實(shí)例的操作符:

of()傳入多個(gè)參數(shù)猜煮,observer將會(huì)將其依次next()傳出,完成時(shí)則傳出complete()

var source = Rx.Observable.of('Jerry', 'Anna');

from()與of()很相似败许,只不過傳入的是一個(gè)可以被枚舉的參數(shù)王带,例如array,set市殷,iterator甚至是promise(可以使用fromPromise)等等(object和string應(yīng)該能被傳入)

var source = Rx.Observable.from(['Jerry', 'Anna']);

fromEvent()用于監(jiān)聽事件愕撰,在next中傳回的將是被觸發(fā)的事件對象

var source = Rx.Observable.fromEvent(document.body, 'click');

fromEventPattern()傳入一個(gè)事件的觸發(fā)與取消,監(jiān)聽一次?

var source = Rx.Observable

? ? .fromEventPattern(

? ? ? ? (handler) => egghead.addListener(handler),

? ? ? ? (handler) => egghead.removeListener(handler)

? ? );

empty()傳入一個(gè)空的觀測序列搞挣,被訂閱后立刻輸出complete

var source = Rx.Observable.empty();

never()傳入一個(gè)永遠(yuǎn)不會(huì)結(jié)束但什么也不干的觀測序列带迟,被訂閱后什么都不會(huì)發(fā)生

var source = Rx.Observable.never();

throw()傳入一個(gè)立刻回拋出異常的觀測序列,被訂閱后立刻拋出這個(gè)錯(cuò)誤

var source = Rx.Observable.throw('Oop!');

interval()傳入一個(gè)按interval傳入?yún)?shù)(單位為ms)間隔發(fā)出next(從0開始)的觀測序列,其中next()傳出的值為次數(shù)囱桨,由0開始

var source = Rx.Observable.interval(1000);

timer()與之類似仓犬,當(dāng)傳入一個(gè)參數(shù)時(shí)類似于setTimeout,當(dāng)設(shè)定兩個(gè)參數(shù)時(shí)蝇摸,第一個(gè)參數(shù)表示第一次next拋出的時(shí)間婶肩,第二個(gè)參數(shù)表示每次next的間隔

var source = Rx.Observable.timer(1000, 5000);

var source = Rx.Observable.timer(1000);

分割線-------------------------------------------------------------------------------------------------------------------------------------------------------------------

Operator:

map()將原有observable按一定規(guī)則映射成為一個(gè)新的observable

var source = Rx.Observable.interval(1000);

var newest = source.map(x => x + 2);

mapTo()將原有observable按映射成為一個(gè)傳出定值的observable

var source = Rx.Observable.interval(1000);

var newest = source.mapTo(2);

filter()將原有的observable根據(jù)規(guī)則過濾成為一個(gè)新的observable

var source = Rx.Observable.interval(1000);

var newest = source.filter(x => x % 2 === 0);

take()取原有的observable的前n項(xiàng),并傳出complete()

var source = Rx.Observable.interval(1000);

var example = source.take(3);

first()等同于take(1)

takeLast()指去最后n個(gè)貌夕,順序依然是正序

var source = Rx.Observable.interval(1000).take(6);

var example = source.takeLast(2);? ? ? ? ? // 輸出4,5

last()等同于takeLast(1)

skip()跳過n個(gè)next

var source = Rx.Observable.interval(1000);

var example = source.skip(3);

takeUntil()在某件事發(fā)生時(shí)律歼,出發(fā)observable的complete()

var source = Rx.Observable.interval(1000);

var click = Rx.Observable.fromEvent(document.body, 'click');

var example = source.takeUntil(click);

concat()把多個(gè)Observable合并成一個(gè)

var source = Rx.Observable.interval(1000).take(3);

var source2 = Rx.Observable.of(3)

var source3 = Rx.Observable.of(4,5,6)

var example = source.concat(source2, source3);

startWith()是在原observable發(fā)送之前添加一些不是observable但是需要被發(fā)送的元素

var source = Rx.Observable.interval(1000);

var example = source.startWith(0);

concatAll()將一個(gè)內(nèi)含Observable的Observable中的所有Observable合并成為一個(gè)Observable

var obs1 = Rx.Observable.interval(1000).take(5);

var obs2 = Rx.Observable.interval(500).take(2);

var obs3 = Rx.Observable.interval(2000).take(1);

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

var example = source.concatAll();

concat和concatAll會(huì)嚴(yán)格按順序執(zhí)行,如上文例子輸出為0,1,2,3,4,0,1,0

merge()與concat類似啡专,但是最大的區(qū)別在于多個(gè)observable會(huì)并發(fā)進(jìn)行险毁,任意一個(gè)observable發(fā)送next時(shí)都會(huì)對之進(jìn)行處理

var source = Rx.Observable.interval(500).take(3);

var source2 = Rx.Observable.interval(300).take(6);

var example = source.merge(source2);

一個(gè)簡單的RxJs拖拽代碼

const dragDOM = document.getElementById('drag');

const body = document.body;

const mouseDown = Rx.Observable.fromEvent(dragDOM, 'mousedown');

const mouseUp = Rx.Observable.fromEvent(body, 'mouseup');

const mouseMove = Rx.Observable.fromEvent(body, 'mousemove');

mouseDown

.map(event => mouseMove.takeUntil(mouseUp))? ? ? ? ? ? ? ? ? ? //這兩行比較精髓個(gè)人感覺

? .concatAll()

? .map(event => ({ x: event.clientX, y: event.clientY }))

? .subscribe(pos => {

? dragDOM.style.left = pos.x + 'px';

? ? dragDOM.style.top = pos.y + 'px';

? })

分割線-------------------------------------------------------------------------------------------------------------------------------------------------------------------

combineLatest()每當(dāng)一個(gè)observable輸出數(shù)據(jù)時(shí)則調(diào)用回調(diào)函數(shù),若另一個(gè)observable并沒有數(shù)據(jù)輸出則不調(diào)用回調(diào)函數(shù)。

var source = Rx.Observable.interval(500).take(3);

var newest = Rx.Observable.interval(300).take(6);

var example = source.combineLatest(newest, (x, y) => x + y);

source : ----0----1----2|

newest : --0--1--2--3--4--5|

combineLatest(newest, (x, y) => x + y);

example: ----01--23-4--(56)--7|

輸出拆分為 0+0们童, 1+0畔况, 2+0,1+2慧库,3+1跷跪,4+1,2+4齐板,5+2吵瞻;

withLatestFrom()與combineLastest類似,但是只有主函數(shù)輸出時(shí)才會(huì)執(zhí)行回調(diào)函數(shù)

var main = Rx.Observable.from('hello').zip(Rx.Observable.interval(500), (x, y) => x);

var some = Rx.Observable.from([0,1,0,0,0,1]).zip(Rx.Observable.interval(300), (x, y) => x);

var example = main.withLatestFrom(some, (x, y) => {

? ? return y === 1 ? x.toUpperCase() : x;

});

訂閱后輸出helLO

zip()則是把每個(gè)observable相同發(fā)送次數(shù)的值放在一次進(jìn)行操作

var source = Rx.Observable.interval(500).take(3);

var newest = Rx.Observable.interval(300).take(6).takeLast(4);

var example = source.zip(newest, (x, y) => x + y);

source : ----0----1----2|

newest : --2--3--4--5|

? ? zip(newest, (x, y) => x + y)

example: ----2----4----6|

輸出拆分為:0+2,1+3,2+4

利用zip我們能很方便的將同步的一些observable變成異步的甘磨,比如

var source = Rx.Observable.from('hello');

var source2 = Rx.Observable.interval(100);

var example = source.zip(source2, (x, y) => x);

這個(gè)例子就能將hello的字母每經(jīng)過100ms輸出一個(gè)橡羞。

分割線-------------------------------------------------------------------------------------------------------------------------------------------------------------------

scan()類似于js的reduce方法,即會(huì)保留上一次next的結(jié)果值并傳入下一次計(jì)算的回調(diào)函數(shù)济舆,作為第一個(gè)參數(shù)

var source = Rx.Observable.from('hello')

? ? ? ? ? ? .zip(Rx.Observable.interval(600), (x, y) => x);

var example = source.scan((origin, next) => origin + next, '');

source : ----h----e----l----l----o|

? ? scan((origin, next) => origin + next, '')

example: ----h----(he)----(hel)----(hell)----(hello)|

buffer()會(huì)將一個(gè)observable的next輸出暫存起來卿泽,直到另一個(gè)observable傳出next時(shí)將緩存區(qū)內(nèi)的所有數(shù)據(jù)通過數(shù)組形式傳出。

var source = Rx.Observable.interval(300);

var source2 = Rx.Observable.interval(1000);

var example = source.buffer(source2);

source : --0--1--2--3--4--5--6--7..

source2: ---------0---------1--------...

? ? ? ? ? ? buffer(source2)

example: ---------([0,1,2])---------([3,4,5])

bufferTime()則是設(shè)定一個(gè)緩存周期滋觉,每經(jīng)過這一個(gè)周期則將緩存內(nèi)的數(shù)據(jù)通過數(shù)組傳出签夭。

var source = Rx.Observable.interval(300);

var example = source.bufferTime(1000);

bufferCount()則設(shè)定一個(gè)緩存大小,每當(dāng)緩存達(dá)到大小時(shí)將數(shù)據(jù)輸出

var source = Rx.Observable.interval(300);

var example = source.bufferCount(3);

bufferToggle()傳入一個(gè)Open Observable和一個(gè)Close Observable以及一個(gè)source Observable椎瘟,每當(dāng)Close傳出一個(gè)

next時(shí)覆致,查找Open的上一個(gè)next(),則將這兩個(gè)next()區(qū)間內(nèi)的所有source的next傳出肺蔚。

const source$ = Rx.Observable.interval(500);

const open$ = Rx.Observable.interval(1500);

const close$ = Rx.Observable.interval(1000);

const foo$ = source$.bufferToggle(open$, ( ) => {

? return close$;

});

/**

---0---1---2---3---4---5---6---7---8---9----....? ? (source)

-----------1-----------2-----------3--------...? ? ? (open)

? ? ? ? ? --- ---x? ? --- ---x? ? --- ---x...? ? ? (close)

? ? ? ? bufferToggle(open$, () => close$)


------------------([2,3])-----([5.6])-----([8,9])--...

*/

bufferWhen()類似與buffer()煌妈,不過bufferWhen的參數(shù)是一個(gè)function,他的返回值為關(guān)閉buffer的observable

const open$ = Rx.Observable.interval(1000);

const click$ = Rx.Observable.fromEvent(document, 'click');

var w = open$.bufferWhen(( ) => click$);

w.subscribe(x => console.log(x))

// 每次點(diǎn)擊都能進(jìn)行一次分組

// 第二秒點(diǎn)擊第一次:[0, 1, 2]

// 第六秒點(diǎn)擊第二次:[3, 4, 5, 6]

分割線-------------------------------------------------------------------------------------------------------------------------------------------------------------------

delay()可以延遲observable一開始發(fā)送next的時(shí)間,也可以傳遞毫秒數(shù),也可以傳遞一個(gè)時(shí)間璧诵。

var source = Rx.Observable.interval(300).take(5);

var example = source.delay(500);

var example2 = source.delay(new Date(Date.now() + 500)); //此二式結(jié)果相同

source : --0--1--2--3--4|

? ? ? ? delay(500)

example: -------0--1--2--3--4|

delayWhen()和delay相似汰蜘,但是最大的不同是他會(huì)延時(shí)每一個(gè)next(),而不像delay只會(huì)延時(shí)第一個(gè)next()

var source = Rx.Observable.interval(300).take(5);

var example = source

? ? ? ? ? ? ? .delayWhen(

? ? ? ? ? ? ? ? ? x => Rx.Observable.empty().delay(100 * x * x)

? ? ? ? ? ? ? );

source : --0--1--2--3--4|

? ? .delayWhen(x => Rx.Observable.empty().delay(100 * x * x));

example: --0---1----2-----3-----4|

debounce()傳入一個(gè)debounce observable,每當(dāng)source observable傳出next時(shí)之宿,不會(huì)立刻將之直接傳出族操,而是將之緩存,

如果在收到debounce傳出的next之前沒有收到其他source傳出的next比被,那么將此次緩存的next傳出色难,否則則將新的source next存入緩存,并等待下一次debounce的來臨等缀。

debounceTime()則是一個(gè)debounce的簡化版枷莉,他接收一個(gè)時(shí)間參數(shù),等同于一個(gè)interval Operator創(chuàng)建的observable尺迂。

//疑問:complete是否與next效果相同笤妙,在下面例子中在觀測前記錄Date.now()并在送出next后幾率Date.now()會(huì)發(fā)現(xiàn)時(shí)間相差會(huì)1.

var source = Rx.Observable.interval(300).take(5);

var oDebounce = Rx.Observable.interval(1000);

var example = source.debounceTime(1000);

var example2 = source.debounce(() => oDebounce);? //此二式效果相同

source : --0--1--2--3--4|

? ? ? ? debounceTime(1000)

example: --------------4|?

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市噪裕,隨后出現(xiàn)的幾起案子蹲盘,更是在濱河造成了極大的恐慌,老刑警劉巖膳音,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件召衔,死亡現(xiàn)場離奇詭異,居然都是意外死亡祭陷,警方通過查閱死者的電腦和手機(jī)薄嫡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來颗胡,“玉大人,你說我怎么就攤上這事吩坝《疽蹋” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵钉寝,是天一觀的道長弧呐。 經(jīng)常有香客問我,道長嵌纲,這世上最難降的妖魔是什么俘枫? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮逮走,結(jié)果婚禮上鸠蚪,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好茅信,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布盾舌。 她就那樣靜靜地躺著,像睡著了一般蘸鲸。 火紅的嫁衣襯著肌膚如雪妖谴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天酌摇,我揣著相機(jī)與錄音膝舅,去河邊找鬼。 笑死窑多,一個(gè)胖子當(dāng)著我的面吹牛仍稀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怯伊,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼琳轿,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耿芹?” 一聲冷哼從身側(cè)響起崭篡,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吧秕,沒想到半個(gè)月后琉闪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砸彬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年颠毙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片砂碉。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛀蜜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出增蹭,到底是詐尸還是另有隱情滴某,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布滋迈,位于F島的核電站霎奢,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏饼灿。R本人自食惡果不足惜幕侠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望碍彭。 院中可真熱鬧晤硕,春花似錦悼潭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至创译,卻和暖如春抵知,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背软族。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工刷喜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人立砸。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓掖疮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親颗祝。 傳聞我的和親對象是個(gè)殘疾皇子浊闪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)螺戳,斷路器搁宾,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • 轉(zhuǎn)載Subject 其實(shí)在 RxJS 中最常被誤解的一部份,因?yàn)?Subject 可以讓你用命令式的方式雖送值到一...
    readilen閱讀 1,635評論 0 5
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,453評論 0 13
  • 找到fullcalendar.js倔幼, 找到代碼為 isRTL:false盖腿,這句話 輸入以下幾句 monthName...
    迷你小小白閱讀 1,665評論 0 1
  • 私心貪念誰沒有? 合乎情理有卻無损同。 享樂為己少思慮翩腐, 奉公利人思而多。
    張旭鋒閱讀 143評論 0 1