免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
開(kāi)發(fā) | 技術(shù)高人如何開(kāi)發(fā)小程序?他們用這套方法
文 | 接灰的電子產(chǎn)品
對(duì)于我這種「不用 Rx 會(huì)死星人」來(lái)說(shuō),如果一個(gè)平臺(tái)沒(méi)有 Rx,在上面寫(xiě)代碼會(huì)很痛苦。
所以,自從我開(kāi)始開(kāi)發(fā)微信小程序以來(lái),就在一直在研究怎么把 RxJS 引入到微信小程序中。
這幾天,我終于有了階段性成果。那「Rx」為什么加引號(hào)?嗯,原因是……經(jīng)過(guò)幾天的艱苦奮戰(zhàn),我還是沒(méi)找到把 RxJS 庫(kù)正確引入到微信小程序的方法。
實(shí)際上,我找了一個(gè)替代品:XStream ( https://github.com/staltz/xstream )。這個(gè)類庫(kù)呢,和 RxJS 差不多,但更輕量。
相比 RxJS,XStream 去掉了好多不常用的和重復(fù)的操作符,當(dāng)然寫(xiě)法上也略有區(qū)別。用起來(lái),XStream 沒(méi)有 RxJS 爽,但問(wèn)題不大。
XStream 的引入
和網(wǎng)上的其他類庫(kù)比較起來(lái),XStream 引入的步驟不算太煩:
  1. 找一個(gè)目錄,npm install xstream 一下;

  2. 在小程序工程目錄下新建一個(gè) libs 目錄,然后再建一個(gè) xstream 目錄。

  3. 然后在 node_modules/xstream 目錄中把 index.js 拷貝到 libs/xstream 下。

  4. node_modules/symbol-observable/lib 中,把 index.jsponyfill.js 都拷貝到 libs/xstream 下。

  5. index.js 改名成 symbol-observable.js,要不然,就會(huì)遇到重名問(wèn)題。

  6. 如果你需要一些其他操作符,可以去 node_modules/xstream/extra 中找,找到后把相應(yīng)的 JS 文件(比如 debounce.js)拷貝到 libs/xstream/extra 中。

好了,XStream 的引入至此已經(jīng)完畢,我們看看,如何在小程序工程中使用 XStream 吧。
先來(lái)體驗(yàn)一下什么是流式編程。在 pageParams.onLoad 中加上如下代碼——當(dāng)然,別忘了引入 XStream。

到 Console 中看一下,輸出結(jié)果為 0、4completed。

我們來(lái)手動(dòng)復(fù)原一下過(guò)程,首先 xs.periodic(1000),是這樣一個(gè)流:

  • 第一秒時(shí),發(fā)射 00 是偶數(shù),滿足 filter 條件,進(jìn)入轉(zhuǎn)換。0 的平方還是 0,結(jié)束條件未滿足,于是輸出 0;

  • 第二秒時(shí),發(fā)射 11 為奇數(shù),被淘汰;

  • 第三秒時(shí),發(fā)射 2,2 是偶數(shù),滿足 filter 條件,進(jìn)入轉(zhuǎn)換。2 的平方是 4,結(jié)束條件未滿足,于是輸出 4;

  • 第四秒時(shí),發(fā)射 3,3 為奇數(shù),被淘汰;

  • 第五秒時(shí),輸出 4,4 是偶數(shù),滿足 filter 條件,進(jìn)入轉(zhuǎn)換。4 的平方是 16,但結(jié)束條件已滿足,輸出 completed。

這個(gè)小例子雖然簡(jiǎn)單,但是涉及到了多個(gè)流式編程的操作符。這種串(chain)起來(lái)的感覺(jué)真是很爽。
微信小程序中的響應(yīng)式編程
由于微信小程序的基于回調(diào)函數(shù)的設(shè)計(jì),我們需要對(duì)其 API 進(jìn)行封裝后使其具備響應(yīng)式編程的能力。
首先,沒(méi)用 XStream 的時(shí)候,代碼是下面這樣的。

接下來(lái),我們用 XStream 改造一下吧:

天啊,這比原來(lái)代碼還多,怎么回事?
先別急,前面的一大部分代碼,是在將傳統(tǒng)的函數(shù)改造成流式的函數(shù)
這些改造工作如果在普通的 HTML+Javascript 環(huán)境中是很好解決的,因?yàn)椴徽撌?RxJS 還是 XStream,都提供了轉(zhuǎn)換類操作符,可以方便的幫我們進(jìn)行轉(zhuǎn)換。
但現(xiàn)在不行啊,這些老外的類庫(kù)寫(xiě)的時(shí)候肯定不會(huì)考慮微信的。那怎么辦?只好自己寫(xiě)吧。

還是這個(gè)例子,我們創(chuàng)建一個(gè)叫 http.js 的文件。在這里,我們對(duì)應(yīng) 4 種網(wǎng)絡(luò)請(qǐng)求方法(GET,POST,PUT,DELETE),分別構(gòu)造了專門(mén)的函數(shù)用語(yǔ)轉(zhuǎn)換。

工具類建好之后,我們onLoad 函數(shù)就變得很簡(jiǎn)單了,是吧?

你想了一下跟我說(shuō):你在逗我嗎?我不用 XStream 也可以這樣封裝,代碼也會(huì)簡(jiǎn)潔很多啊。
別急,我們費(fèi)這么大勁把它轉(zhuǎn)換成流式函數(shù),不是只是為了簡(jiǎn)潔,而是能夠使用響應(yīng)式編程更多特性。
比如,上面的代碼我們加一個(gè)需求:在出錯(cuò)后再進(jìn)行若干次重試,但需要控制總用時(shí)。這個(gè)需求很常見(jiàn),但是常規(guī)寫(xiě)法很復(fù)雜。
我們看看用響應(yīng)式編程方式怎么做。

上面代碼中,我們每隔一秒(periodic(1000)),輸出一個(gè)從 0 開(kāi)始、每次增長(zhǎng) 1 的自然數(shù)。
接著,在轉(zhuǎn)換函數(shù)中生成一個(gè) 1-10 的隨機(jī)數(shù)。如果前面數(shù)據(jù)流發(fā)射的數(shù)大于這個(gè)隨機(jī)數(shù),我們就手動(dòng)拋出一個(gè)異常,反之原樣返回這個(gè)數(shù)字。
定義好這個(gè)數(shù)據(jù)流后,我們按需求進(jìn)行處理:
  1. 遇到異常應(yīng)該重試,那我們使用 replaceError((err) => demo$),每次遇到異常,我們都再執(zhí)行一遍前面的數(shù)據(jù)流;

  2. 我們應(yīng)該控制超時(shí)時(shí)間 10 秒,所以使用 .endWhen(xs.periodic(10000))。

這樣,我們就輕松地解決了這個(gè)問(wèn)題。
我們來(lái)看看輸出,一開(kāi)始從 0 到 3 都比較正常,然后程序拋出了異常。replaceError((err) => demo$) 捕獲到這個(gè)異常,并且用 demo$ 替換錯(cuò)誤,也就是說(shuō)再次執(zhí)行。
慢著,那不是死循環(huán)了嗎?沒(méi)事,我們?cè)O(shè)定了一個(gè)退出條件,就是 10 秒結(jié)束該流。
在這個(gè)過(guò)程中,我們需要注意:在 XStream 中所有的流默認(rèn)都是 Hot Observable。
怎么理解這個(gè)概念呢?
想象一下,我們?cè)诳措娨曋辈?,我們所有的人不管你是什么時(shí)候打開(kāi)的電視,我們開(kāi)的內(nèi)容、進(jìn)度都是一樣的。這就是 Hot Observable。
但 Cold Observable 并不一樣,相當(dāng)于是網(wǎng)絡(luò)視頻。你看到第 20 分鐘后我才打開(kāi)這個(gè)視頻,這個(gè)時(shí)候,我的觀看進(jìn)度是從頭開(kāi)始的。
下面是用 RxJS 寫(xiě)的一個(gè)每隔 1 秒生成一個(gè)增長(zhǎng) 1 的自然數(shù)流,第二個(gè)用戶在前一個(gè)用戶 2 秒之后開(kāi)始使用。我們會(huì)看到下面的情況。

同樣的邏輯,用 XStream 實(shí)現(xiàn)的代碼,出來(lái)的是另一番景象。

當(dāng)然在很多場(chǎng)景中,這種差別不會(huì)帶來(lái)本質(zhì)的變化。比如 HTTP 請(qǐng)求,本身就是一次性的請(qǐng)求,所以 hot 和 cold 的結(jié)果是一樣的。
RxJS 作為大而全的類庫(kù),當(dāng)然會(huì)同時(shí)支持 Hot Observable 和 Cold Observable 的。
XStream 的作者其實(shí)也是 RxJS 的 contributor(貢獻(xiàn)者)。但他認(rèn)為,在 web 前端領(lǐng)域,hot 的應(yīng)用頻率遠(yuǎn)比 cold 要多,所以做了這個(gè)精簡(jiǎn)版的響應(yīng)式類庫(kù)。
事件的處理
上述方法用于普通 API 的封裝一點(diǎn)問(wèn)題也沒(méi)有,但是在做輸入事件時(shí),我遇到了一些小麻煩。
獲取輸入事件不困難。小程序輸入事件,也是綁定在 WXML 中的 控件中,用 bindinput 來(lái)指定一個(gè) eventHandler。我將它定名為 addTodo。

標(biāo)準(zhǔn)的微信小程序,可以這樣來(lái)寫(xiě)事件處理。

如果要把事件截獲并以數(shù)據(jù)流輸出的話,我們需要onLoad 中進(jìn)行事件處理函數(shù)的定義。
比如下面的代碼可以讓我們實(shí)現(xiàn)對(duì)于輸入事件的定義,在其定義中我們其實(shí)使用了流數(shù)據(jù)的發(fā)射作為其函數(shù)體。

這樣封裝后,我們可以使用一些操作符來(lái)實(shí)現(xiàn)諸如濾波器等功能。
下面的代碼片段,就是用于過(guò)濾快速輸入(小于 400 毫秒)事件的。

但這種的封裝有個(gè)問(wèn)題:我們要把這個(gè)封裝提取為一個(gè)單獨(dú)函數(shù)時(shí),由于 this.addTodo 仍未初始化,它就無(wú)法作為參數(shù)傳遞,而且 addTodo 也不能寫(xiě)死。
怎么辦?我試了幾種方案后,選取了使用 Object.defineProperty 的形式,動(dòng)態(tài)定義 pageParams 對(duì)象的命名屬性的方法。
當(dāng)然,這個(gè)方法還是有一些問(wèn)題,比如,你仍然需要給這些方法一個(gè)初始值(有同學(xué)如果有更好的建議請(qǐng)指教)。
下面就是目前實(shí)現(xiàn)的抽象封裝代碼。在下面的代碼中,由于我們對(duì)外發(fā)射的是事件(event),所以其實(shí)它不光可以用于輸入事件,理論上任意事件都可以。
也就是說(shuō),我們自己實(shí)現(xiàn)了類似 Rx.Observable.fromEvent 的功能。

最后的話
我為了能在微信順利使用 XStream,建立了一個(gè) Github 項(xiàng)目,名叫 wxstream (https://github.com/wpcfan/wxstream)。
這名字的意思,其實(shí)就是「微信+XStream」。只要把這個(gè)項(xiàng)目拉下來(lái),拷貝到微信小程序目錄,就立即可用了,包括 XStream 的支持都在里面了。
目前還沒(méi)什么文檔,大部分接口都沒(méi)測(cè)過(guò)。后續(xù)我逐漸添加文檔和進(jìn)行測(cè)試,現(xiàn)在只是個(gè)骨架,大家也幫忙測(cè)一下吧 ;-)。
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Spartacus Product List Page ProductSearchPage Observable 對(duì)象的設(shè)計(jì)明細(xì)
Rxjs 核心概念
反應(yīng)式編程詳解
深入淺出RxJava07——多線程&輔助操作
2017年最值得學(xué)習(xí)的前端框架和技術(shù) – WEB前端開(kāi)發(fā)
目前最好的 JavaScript 異步方案 async/await
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服