免费国产欧美国日产_少妇AV一区二区三区无码_蜜桃精品av无码喷奶水小说_jk18禁网站视频_精产国品一二三级产品区别_被夫の上司に犯波多野结衣_78m成人手机免费看_最爽最刺激18禁视频_偷偷色噜狠狠狠狠的777米奇

易優(yōu)GEO 重磅上線(xiàn) ~ 一站式GEO優(yōu)化工具,讓豆包、文心一言、DeepSeek 在回答中主動(dòng)推薦你的品牌,搶占AI流量入口!  點(diǎn)擊查看

小程序模板網(wǎng)

用 RxJS、RxWX 編寫(xiě)更優(yōu)秀的微信小程序代碼

發(fā)布時(shí)間:2018-01-02 09:04 所屬欄目:小程序開(kāi)發(fā)教程

好的代碼通常符合一個(gè)特點(diǎn):高內(nèi)聚,低耦合。通俗地說(shuō)就是用更少地代碼完成更多地功能,比如web前端地MVVM框架就是把對(duì)DOM的操作和事件監(jiān)聽(tīng)抽象出來(lái),通過(guò)數(shù)據(jù)綁定來(lái)更新數(shù)據(jù)和視圖。“組件化”的思想也是如此,組件 ...

 
 
 

好的代碼通常符合一個(gè)特點(diǎn):高內(nèi)聚,低耦合。

通俗地說(shuō)就是用更少地代碼完成更多地功能,比如web前端地MVVM框架就是把對(duì)DOM的操作和事件監(jiān)聽(tīng)抽象出來(lái),通過(guò)數(shù)據(jù)綁定來(lái)更新數(shù)據(jù)和視圖。

“組件化”的思想也是如此,組件的目的不是簡(jiǎn)單的代碼分割,更重要的是方便代碼的復(fù)用。

這些都是針對(duì)視圖層面的優(yōu)化措施,針對(duì)數(shù)據(jù)層,其實(shí)也有方法寫(xiě)出更優(yōu)秀的代碼。

其中一個(gè)簡(jiǎn)單有效的方法就是 盡量編寫(xiě)純函數(shù)。

純函數(shù)

什么是純函數(shù)?可以用一個(gè)表達(dá)式來(lái)描述

輸入?yún)?shù)x => 執(zhí)行代碼 => 輸出結(jié)果y

這看起來(lái)好像和普通函數(shù)也沒(méi)啥區(qū)別,那么它和普通的函數(shù)相比,“純”在哪里?

  • 從輸入來(lái)看,參數(shù)是必傳的,而且不能被修改。比如 Math.random 這類(lèi)沒(méi)有參數(shù)的函數(shù)就不是純函數(shù)。

  • 從執(zhí)行來(lái)看,不能引用外部變量或函數(shù)。

  • 從結(jié)果來(lái)看,執(zhí)行必有結(jié)果,而且輸入相同的參數(shù),執(zhí)行的結(jié)果必須相同。

純函數(shù)是將邏輯分離到極致:一段功能單一,邏輯封閉的代碼。

思考:function(x) { return 1 } 是不是純函數(shù)?

如果你的代碼中使用純函數(shù),會(huì)帶來(lái)以下好處:

  • 易測(cè)試。寫(xiě)過(guò)單元測(cè)試的前端開(kāi)發(fā)都知道,前端的單元測(cè)試是很難寫(xiě)的,其中很大一個(gè)原因就是“不純”的函數(shù)太多,一個(gè)函數(shù)可能既要操作DOM,又要發(fā)送ajax請(qǐng)求,還可能引用了不知名的全局變量…AngularJS在官方文檔中就直接指出有些耦合性高的代碼是難以測(cè)試的,所以這也是近些年MVVM框架流行的原因,框架承擔(dān)了DOM操作,開(kāi)發(fā)者只負(fù)責(zé)寫(xiě)邏輯,從而讓代碼邏輯更清晰。

  • 可復(fù)用。 使用Node.js編寫(xiě)服務(wù)端的同學(xué)對(duì)一個(gè)詞肯定熟悉——“同構(gòu)”,也就是說(shuō),一份js代碼可以同時(shí)在服務(wù)端和瀏覽器端正常運(yùn)行,而純函數(shù)是支持同構(gòu)的。

  • 無(wú)副作用。比如多個(gè)不純的函數(shù)同時(shí)修改一個(gè)變量(或操作一個(gè)DOM元素),再加上異步等情況,這樣就很容易引起沖突。而純函數(shù)既不修改入?yún)⒁膊恍薷耐獠孔兞?,所以完全不用?dān)心。

RxJS

符合純函數(shù)特點(diǎn)的第三方開(kāi)源庫(kù)有非常著名的underscore和lodash,以及更加強(qiáng)大的RxJS。

RxJS是微軟推出的ReactiveX系列(RxJava,Rx.NET,RxScala,RxSwift等)中的一員,目前Github上star數(shù)已經(jīng)超過(guò)17k。

它可以用來(lái)優(yōu)雅地處理異步和事件。主要通過(guò)它的核心類(lèi)型 Observable,以及強(qiáng)大的操作符 (map、filter、reduce、every等,其中大部分都是純函數(shù))來(lái)實(shí)現(xiàn)。

官方給它最直白的定義是

可以把 RxJS 當(dāng)做是用來(lái)處理事件的 Lodash 。

來(lái)一段官方的代碼體驗(yàn)一下:

// 使用普通的 JavaScript 控制按鈕一秒鐘內(nèi)只允許點(diǎn)擊一次
var count = 0;
var rate = 1000;
var lastClick = Date.now() - rate;
var button = document.querySelector('button');
button.addEventListener('click', () => {
  if (Date.now() - lastClick >= rate) {
    console.log(`Clicked ${++count} times`);
    lastClick = Date.now();
  }
});

// 使用Rx.js實(shí)現(xiàn)
var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .throttleTime(1000)
  .scan(count => count + 1, 0)
  .subscribe(count => console.log(`Clicked ${count} times`));

使用RxJS的代碼消除了一些中間變量,使用操作符來(lái)分步執(zhí)行邏輯,可讀性更強(qiáng)、耦合性更低,更方便測(cè)試和修改。

關(guān)于RxJS更詳細(xì)介紹在以后的文章中再敘,本文先談一談它的應(yīng)用。關(guān)于RxJS在web端和node.js服務(wù)端的應(yīng)用都不乏文章,所以這一次突破常規(guī),來(lái)講一講在微信小程序(以下簡(jiǎn)稱(chēng)“小程序”)開(kāi)發(fā)中的使用。

小程序

直接在小程序中使用RxJS是會(huì)報(bào)錯(cuò)的,所以我建立了一個(gè)開(kāi)源項(xiàng)目來(lái)解決這個(gè)問(wèn)題:RxWX(項(xiàng)目地址:https://github.com/yalishizhude/RxJS )。

封裝了兩個(gè)js文件。

  • Rx.js。對(duì)Rx.js進(jìn)行了一些修改使其能在小程序中運(yùn)行。

  • RxWX.js?;赗x.js對(duì)微信的api進(jìn)行了封裝,調(diào)用同名API不再使用回調(diào),而是返回Observalbe對(duì)象。

安裝

提供兩種安裝途徑

Github

git clone https://github.com/yalishizhude/RxWX.git

可以直接下載項(xiàng)目,將根目錄的Rx.js和RxWX.js復(fù)制到小程序項(xiàng)目中,也可以訪(fǎng)問(wèn)該網(wǎng)址復(fù)制粘貼這兩個(gè)文件內(nèi)容。

npm

npm i rxjs-wx

將node_modules/rxjs-wx目錄下的Rx.js和RxWX.js復(fù)制到小程序項(xiàng)目中。

使用

小程序的API大多數(shù)都不是按照純函數(shù)的思想設(shè)計(jì)的,把返回結(jié)果賦值給入?yún)⒌膕uccess、fail、complete屬性。

在邏輯簡(jiǎn)單復(fù)雜的情況下很容墮入“回調(diào)地獄”,而且同步和異步的接口調(diào)用方式也不一致。而使用RxJS就可以解決這些問(wèn)題,下面來(lái)看幾個(gè)例子。

處理回調(diào)

假設(shè)有這樣一個(gè)需求,先通過(guò) wx.getUserInfo 獲取用戶(hù)信息,然后傳給后端服務(wù)獲取該用戶(hù)其它信息,顯示在頁(yè)面上。

// 普通代碼
let self = this
wx.getUserInfo({
  success: (res) => {
    wx.request({
      method: 'GET',
      url: 'xxx/user',
      data: res.userInfo,
      success(r) {
        self.setData({userInfo:r})
      },
      fail(e) {
        self.setData({userInfo:'not found'})
      }
    })
  },
  fail(e) {
    console.error(e)
  }
})

// 使用RxWX
import obs from './RxWX'

obs.getUserInfo()
  .catch(e => console.error(e))
  .switchMap(({ userInfo }) => obs.request({ method: 'GET', url: 'xxx/user', data: user }))
  .subscribe(userInfo => self.setData({ userInfo: r }), e => self.setData({ userInfo: 'not found' }))

處理事件

曾經(jīng)在開(kāi)發(fā)小程序的時(shí)候使用navigator組件碰到一個(gè)比較嚴(yán)重的問(wèn)題:快速多次點(diǎn)擊的時(shí)候會(huì)發(fā)生多次頁(yè)面跳轉(zhuǎn),跳轉(zhuǎn)完成后需要多次點(diǎn)擊“返回”才能退回到原頁(yè)面。

為了解決這個(gè)問(wèn)題,一般可以手動(dòng)綁定事件,然后進(jìn)行一個(gè)防抖操作。

// 普通代碼
let tapping = false
...
tap(e) {
  if(!tapping) {
    wx.navigateTo({ url: '../demo/demo' })
    tapping = true
    setTimeout(() => tapping=false, 1000)
  }
}

// 使用RxWX
import obs from './RxWX'

tap(e) {
  obs.navigateTo({ url: '../demo/demo' })
  .debounce(1000)
  .subscribe()
}

其它

RxWX同時(shí)還支持wx對(duì)象的其它非函數(shù)屬性,比如:

import obs from './RxWX'

console.log(obs.version) 
// {info:"", updateTime:"2017.7.10 19:35:05", version:"1.4.0"}

最后

RxJS和RxWX是第三方庫(kù),也是進(jìn)入純函數(shù)世界的大門(mén),更是一種編寫(xiě)更好代碼的思維方式。

 

本文作者小程序聯(lián)盟社區(qū)博主 yalishizhude,搜索關(guān)注個(gè)人公眾號(hào)“web學(xué)習(xí)社”~

本文可被轉(zhuǎn)發(fā)或分享,但必須保留完整圖文信息和出處,作者保留追究一切法律責(zé)任的權(quán)利和手段~ 



易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開(kāi)源 碼云倉(cāng)庫(kù):starfork
本文地址:http://www.szcjxy.com/wxmini/doc/course/18342.html 復(fù)制鏈接 如需定制請(qǐng)聯(lián)系易優(yōu)客服咨詢(xún): 點(diǎn)擊咨詢(xún)
在線(xiàn)客服