跟我學(xué)Rx編程——背景音樂(lè)按鈕

有些H5的頁(yè)面會(huì)有一個(gè)按鈕控制背景音樂(lè)播放负敏,如果只是單一頁(yè)面的話吼过,沒(méi)有什么邏輯可言。但如果涉及到轉(zhuǎn)場(chǎng)苛谷,那么邏輯就復(fù)雜起來(lái)。

涉及操作符

  • partition
  • switchMapTo
  • takeUntil

業(yè)務(wù)邏輯

  1. 點(diǎn)擊背景音樂(lè)按鈕格郁,則播放音樂(lè)腹殿,再次點(diǎn)擊暫停播放音樂(lè)
  2. 當(dāng)切換場(chǎng)景的時(shí)候,如果音樂(lè)正在播放例书,則切換新的場(chǎng)景的背景音樂(lè)
  3. 當(dāng)切換場(chǎng)景的時(shí)候锣尉,如果音樂(lè)已經(jīng)暫停,則等待點(diǎn)擊后再播放新的音樂(lè)
  4. 當(dāng)有音樂(lè)的時(shí)候决采,按鈕播放旋轉(zhuǎn)動(dòng)畫自沧,暫停播放時(shí)按鈕靜止不動(dòng)

對(duì)于使用者來(lái)說(shuō)再正常不過(guò)的邏輯,開(kāi)發(fā)起來(lái)卻不是那么容易树瞭,因?yàn)樯婕暗铰曇舻募虞d拇厢,切換,暫停和響應(yīng)點(diǎn)擊等晒喷。

這次我們不再寫常規(guī)操作孝偎,大家可以自行腦補(bǔ)。

RxJS實(shí)現(xiàn)

首先我們定義播放按鈕的事件流凉敲,以及切換場(chǎng)景的事件流

let playMusicClickOb = fromEvent(musicBn, 'click')
let changeStageOb = ...//此處省略創(chuàng)建過(guò)程

接下來(lái)我們需要通過(guò)partition操作符分離出兩個(gè)事件流

let [playingStageOb, muteStageOb] = changeStageOb.pipe(partition(_ => isPlaying))

當(dāng)切換場(chǎng)景的時(shí)候邪媳,正在播放和沒(méi)有播放的情況分成兩個(gè)事件流對(duì)象playingStageOb和muteStageOb

接下來(lái)我們就可以利用上面定義好的4個(gè)事件流組合成我們要的邏輯了

rxjs.merge(playingStageOb, muteStageOb.pipe(switchMapTo(playMusicClickOb.pipe(take(1)), outv => outv))).pipe(map((index => {
            playAni()//按鈕旋轉(zhuǎn)動(dòng)畫
            return Laya.SoundManager.playMusic('stage' + index + ".mp3")
        })), switchMapTo(playMusicClickOb.pipe(takeUntil(muteStageOb)), outV => outV)).subscribe(channel => {
            if (isPlaying) {
                channel.pause()
                stopAni()//停止按鈕旋轉(zhuǎn)動(dòng)畫
            } else {
                channel.resume()
                playAni()//按鈕旋轉(zhuǎn)動(dòng)畫
            }
        })

分析

代碼中分為三個(gè)功能區(qū)

加載音樂(lè)并播放

 playAni()//按鈕旋轉(zhuǎn)動(dòng)畫
return Laya.SoundManager.playMusic('stage' + index + ".mp3")

暫停播放

channel.pause()
stopAni()//停止按鈕旋轉(zhuǎn)動(dòng)畫

恢復(fù)播放

channel.resume()
playAni()//按鈕旋轉(zhuǎn)動(dòng)畫

這個(gè)三塊功能何時(shí)執(zhí)行捐顷,是本案最為關(guān)鍵的部分。
我們來(lái)分析

rxjs.merge(playingStageOb, muteStageOb.pipe(switchMapTo(playMusicClickOb.pipe(take(1)), outv => outv))).pipe(map((index => {

首先雨效,最后的map操作符是為了把場(chǎng)景的序號(hào)轉(zhuǎn)換成對(duì)應(yīng)的mp3文件名迅涮,這個(gè)沒(méi)什么好說(shuō)的,可以忽略

map((index => {

所以核心邏輯就是

rxjs.merge(playingStageOb, muteStageOb.pipe(switchMapTo(playMusicClickOb.pipe(take(1)), outv => outv)))

我們觀察徽龟,最外層是merge操作即

rxjs.merge(playingStageOb, muteStageOb.pipe(...))

意思是轉(zhuǎn)場(chǎng)事件觸發(fā)的事件流叮姑,包括正在播放音樂(lè)時(shí)轉(zhuǎn)場(chǎng),以及不在播放音樂(lè)時(shí)轉(zhuǎn)場(chǎng)据悔。其中不在播放音樂(lè)時(shí)轉(zhuǎn)場(chǎng)還有后續(xù)的操作

switchMapTo(playMusicClickOb.pipe(take(1)), outv => outv)

這句話的意思是传透,如果在靜音的時(shí)候轉(zhuǎn)場(chǎng),就會(huì)開(kāi)始監(jiān)聽(tīng)playMusicClickOb极颓,即按鈕點(diǎn)擊事件朱盐,take(1)只取一次事件,就立即關(guān)閉菠隆,目的是組合出那種狀態(tài)即——靜音后轉(zhuǎn)場(chǎng)兵琳,然后又點(diǎn)擊了播放音樂(lè)的按鈕。
合起來(lái)骇径,就是在下面兩種情況之一就執(zhí)行加載音樂(lè)并播放音樂(lè)和動(dòng)畫的邏輯

  1. 正在播放音樂(lè)時(shí)轉(zhuǎn)場(chǎng)
  2. 靜音時(shí)轉(zhuǎn)場(chǎng)躯肌,然后點(diǎn)擊了播放音樂(lè)的按鈕

下面我們分析身下的邏輯:

  })), switchMapTo(playMusicClickOb.pipe(takeUntil(muteStageOb)), outV => outV)).subscribe(channel => {

這段邏輯建立在之前已經(jīng)加載音樂(lè)并且播放起來(lái)后執(zhí)行。當(dāng)之前的邏輯執(zhí)行后破衔,我們通過(guò)switchMapTo切換成后面這個(gè)事件流

playMusicClickOb.pipe(takeUntil(muteStageOb)), outV => outV)

即如果此時(shí)點(diǎn)擊了音樂(lè)按鈕清女,就會(huì)觸發(fā)直到受到了靜音轉(zhuǎn)場(chǎng)的事件。什么意思晰筛?就是說(shuō)此時(shí)用戶點(diǎn)擊了音樂(lè)播放按鈕嫡丙,就會(huì)在暫停和播放兩種狀態(tài)切換。直到我們暫停的情況下轉(zhuǎn)場(chǎng)了读第,就不再監(jiān)聽(tīng)迄沫。為什么是這樣設(shè)計(jì)呢?假設(shè)我們此時(shí)切換了暫停和播放若干次卦方,我們要轉(zhuǎn)場(chǎng)了羊瘩,如果此時(shí)正好在暫停狀態(tài),那么我轉(zhuǎn)場(chǎng)后盼砍,是什么狀態(tài)呢尘吗?對(duì)了,就是上面

  1. 靜音時(shí)轉(zhuǎn)場(chǎng)浇坐,然后點(diǎn)擊了播放音樂(lè)的按鈕

的狀態(tài)睬捶,看到?jīng)],所以我們使用takeUntil來(lái)終止當(dāng)前事件流近刘。如果是播放音樂(lè)的狀態(tài)下轉(zhuǎn)場(chǎng)了呢擒贸?這就回到了上面的

  1. 正在播放音樂(lè)時(shí)轉(zhuǎn)場(chǎng)

的狀態(tài)臀晃,會(huì)執(zhí)行加載音樂(lè)并播放的邏輯,但我們的切換暫停和播放的功能依舊需要運(yùn)行介劫,所以在takeUntil中我們只有一種情況需要終止當(dāng)前事件流就是muteStageOb

是不是有點(diǎn)繞徽惋,多想想就能明白
利用Rx編程,我們復(fù)用了事件流對(duì)象座韵,組合出了各種狀態(tài)下的邏輯险绘,并將實(shí)際執(zhí)行代碼壓縮到最精簡(jiǎn),假如有邏輯需求變化誉碴,也能很快修改宦棺。比如我們需要一開(kāi)始就播放音樂(lè),只需要在merge里面加一個(gè)of(0)——參數(shù)0沒(méi)有任何意義黔帕,純粹為了觸發(fā)事件

rxjs.merge(of(0),playingStageOb, muteStageOb......
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末代咸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子成黄,更是在濱河造成了極大的恐慌呐芥,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件慨默,死亡現(xiàn)場(chǎng)離奇詭異贩耐,居然都是意外死亡弧腥,警方通過(guò)查閱死者的電腦和手機(jī)厦取,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)管搪,“玉大人虾攻,你說(shuō)我怎么就攤上這事「常” “怎么了霎箍?”我有些...
    開(kāi)封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)澡为。 經(jīng)常有香客問(wèn)我漂坏,道長(zhǎng),這世上最難降的妖魔是什么媒至? 我笑而不...
    開(kāi)封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任顶别,我火速辦了婚禮,結(jié)果婚禮上拒啰,老公的妹妹穿的比我還像新娘驯绎。我一直安慰自己,他們只是感情好谋旦,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布剩失。 她就那樣靜靜地躺著屈尼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拴孤。 梳的紋絲不亂的頭發(fā)上脾歧,一...
    開(kāi)封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音乞巧,去河邊找鬼涨椒。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绽媒,可吹牛的內(nèi)容都是我干的蚕冬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼是辕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼囤热!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起获三,我...
    開(kāi)封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤旁蔼,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后疙教,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棺聊,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年贞谓,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了限佩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡裸弦,死狀恐怖祟同,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情理疙,我是刑警寧澤晕城,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站窖贤,受9級(jí)特大地震影響砖顷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赃梧,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一滤蝠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧槽奕,春花似錦几睛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)囱持。三九已至,卻和暖如春焕济,著一層夾襖步出監(jiān)牢的瞬間纷妆,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工晴弃, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留掩幢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓上鞠,卻偏偏與公主長(zhǎng)得像际邻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芍阎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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

  • 1世曾、通過(guò)CocoaPods安裝項(xiàng)目名稱項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明先生_X自主閱讀 15,981評(píng)論 3 119
  • 你的每一句話,都需要解碼谴咸,不然怎么會(huì)看了再看轮听,一言不發(fā)?耽誤了的何止是萬(wàn)千韶華岭佳,耽誤在這里面血巍,就在這里面靜靜賞花。...
    君子包閱讀 293評(píng)論 2 7
  • 1 早晨在小區(qū)內(nèi)慢跑訓(xùn)練辨赐,感受清新的空氣优俘,每天從好的心情開(kāi)始 2 早晨沒(méi)有出現(xiàn)明顯的困頓的現(xiàn)象京办,全天的精力保持較好...
    LiHongxi閱讀 143評(píng)論 0 0
  • 教師下水文 在喧囂的街市上,你在低頭刷屏帆焕,在擁擠地鐵惭婿、公交車?yán)锏哪阍诘皖^看屏,在繁華的商場(chǎng)里你在低頭...
    四月芳菲五月紅泥閱讀 209評(píng)論 0 3