亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

從命令式到響應(yīng)式(一)

JayChen / 2848人閱讀

摘要:響應(yīng)式命令式這兩種編程風(fēng)格的思維方式是完全相反的。第二種方式是工人主動去找工人索取生產(chǎn)手機(jī)所要的零件,然后生產(chǎn)一臺完整的手機(jī),這兩種方式就對應(yīng)的響應(yīng)式和命令式。

angular2中內(nèi)置了rxjs,雖然框架本身并沒有強(qiáng)制開發(fā)者使用響應(yīng)式風(fēng)格來組織代碼,但是從框架開發(fā)團(tuán)隊(duì)的角度可以看出他們必然是認(rèn)同這種編程風(fēng)格的。rxjs本質(zhì)是基于函數(shù)式編程的響應(yīng)式風(fēng)格的庫,函數(shù)式相對于面向?qū)ο髞碚f更加抽象,響應(yīng)式的思維方式和命令式的思考方式又截然相反,所以導(dǎo)致大多數(shù)的開發(fā)者開始接觸時覺得非常不適應(yīng),認(rèn)為門檻太高,其實(shí)不然,只要思維方式能轉(zhuǎn)變,你會覺得響應(yīng)式是更加順其自然的事情。響應(yīng)式涉及的知識點(diǎn)很多,這篇文章只能做到管中窺豹,讓大家在感性上對它有一個認(rèn)識。

面向?qū)ο?vs 函數(shù)式

抽象層級不同:簡單來說,面向?qū)ο蟪橄罅宋铮瘮?shù)式抽象了行為。最簡單的例子:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.ageAfterYears = function(years) {
    console.log(this.age + years);
}

var john = new Person("John", 18);

面向?qū)ο蟮姆绞?/p>

john.ageAfterYears(5) // 23;

函數(shù)式的方式:

function getAge(baseAge) {
    return (obj) => console.log(obj.age + baseAge);
}

const ageAfterYears = getAge(5);

ageAfterYears(john); // 23;

這段代碼很簡單,但足以說明問題,使用面向?qū)ο蟮姆绞綍r,我們直接調(diào)用person類的方法,計(jì)算出實(shí)例的年齡,我們會很在乎這個對象上是否提供這么一個方法。但使用函數(shù)式時,ageAfterYears函數(shù)并不在乎傳入的對對象上是否有那個方法,只需要傳入的對象有上age屬性,它就可以得一個結(jié)果,我們更在乎的是這種行為是否正確,例如計(jì)算函數(shù)的行為是加,而不是減,或者其它。

響應(yīng)式 vs 命令式

這兩種編程風(fēng)格的思維方式是完全相反的。假設(shè)一個生產(chǎn)手機(jī)的過程,第一種方式是工人 A 先處理零件,然后交給工人 B, 工人 B 接收后生產(chǎn)出一臺手機(jī)。第二種方式是工人 B 主動去找工人 A 索取生產(chǎn)手機(jī)所要的零件,然后生產(chǎn)一臺完整的手機(jī),這兩種方式就對應(yīng)的響應(yīng)式和命令式??梢钥闯?,響應(yīng)式更適合于流水線式的生產(chǎn),因?yàn)樗?jié)省了大量的溝通成本。尤其重要的一點(diǎn)是工人 B的行為是‘懶’的,它不會主動的去爭取任務(wù),而是一直在等待任務(wù)的到來。在程序中,數(shù)據(jù)就是我們產(chǎn)品的零件,因此也適合這種流水線式的處理。假如我們需要控制用戶在一個按鈕上每秒最多只能點(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} timers`);
        lastClick = Date.now();
    }
});

使用響應(yīng)式:

var button = button.querySelector("button");

Rx.Observable.fromEvent(button, "click")
    .throttleTime(1000)
    .scan(count => count + 1, 0)
    .subscribe(count => console.log(`Click ${count} times`));

從代碼上可以看出,命令式的代碼量更大,而響應(yīng)式的只有區(qū)區(qū)幾行,當(dāng)然你可以說這是因?yàn)槭褂昧藃xjs封裝的庫,但更為重要的是在命令式的代碼中變量的數(shù)量更多,尤為糟糕的是這些變量相對于主邏輯來說處于‘全局‘的位置,而javascript中全局變量是魔鬼,我們不得不隨時小心這些定時炸彈。

上面已經(jīng)提到過響應(yīng)式的處理過程是’懶‘的,除此之外,它的優(yōu)點(diǎn)可以概括如下

所有數(shù)據(jù)處理的過程使用操作符的全部都是純函數(shù),它們只是單純的接收輸入,產(chǎn)生輸出,并不會對輸入的值做出任何改變。

rxjs實(shí)現(xiàn)的 Observable 是一個可以產(chǎn)生多個值序列,是一個 push 類型的系統(tǒng),這和 pull 類型的函數(shù)系統(tǒng)有很大的不同。

push vs pull

這里使用 pull 和 push 來描述值的生產(chǎn)者和消費(fèi)者之間是如何發(fā)生聯(lián)系的,它們是兩種完全不同的協(xié)議。

在pull的系統(tǒng)中,值的消費(fèi)決定什么時間從生產(chǎn)者上獲取數(shù)據(jù),生產(chǎn)者本身并不關(guān)心數(shù)據(jù)什么時間分發(fā)給消費(fèi)者。

每一個javascript函數(shù)都可以看作一個 pull 類型的系統(tǒng)。函數(shù)可以產(chǎn)生值,但這是通過調(diào)用者主動調(diào)用函數(shù),函數(shù)運(yùn)行產(chǎn)生出值返回給調(diào)用者的方式進(jìn)行的,所以可以理解為調(diào)用者主動去函數(shù)上拉取了值。

ES2015中介紹另外兩種 pull 類型的系統(tǒng),generator函數(shù) 和 iterator。對于它們來講,遍歷器對象的 next 方法可以視作值的消費(fèi)者,通過iterator.next()可以獲取到多個值。

Producer Consumer
pull 被動:當(dāng)被調(diào)用時產(chǎn)生值 主動:決定何時發(fā)起調(diào)用
push 主動:按自身的設(shè)置產(chǎn)生值 被動:響應(yīng)接收到的值

在push的系統(tǒng)中,生產(chǎn)者決定什么時候發(fā)送值給消費(fèi)者,消費(fèi)者并不知道什么時候可以接收到值。

ES6中的 promise 就是一個非常典型的 push 系統(tǒng),promise 將 resolve 的結(jié)果傳遞給注冊在它內(nèi)部的回調(diào)函數(shù),這與普通的函數(shù)有很大的不同,回調(diào)函數(shù)何時可以接收到數(shù)據(jù)完全取決于 promise 什么時間向它傳遞數(shù)據(jù)。

rxjs的 Observable 也是一種 push 類型的系統(tǒng),一個 Observable 可以產(chǎn)生多個值,然后推送給它的訂閱者。

Function 是一個 ‘懶’ 的求值過程,只有在被調(diào)用時它才會同步的返回一個值給調(diào)用者。

generator 也是一個 ’懶‘ 的求值過種,在遍歷的過程中同步的返回0個或多個值給調(diào)用者。

Promise 經(jīng)過運(yùn)算后可能產(chǎn)生一個值,當(dāng)然也可能產(chǎn)生一個錯誤。

Observable 也是一個‘懶’的求值過程,當(dāng)它被訂閱后可以同步或者異步的產(chǎn)生出0個或者無限多個值給調(diào)用者,這個過程將一直持續(xù)到訂閱被取消或者流結(jié)束。

今天先寫到這里,沒有過多的代碼, 更沒有涉及到angular中如何去應(yīng)用響應(yīng)式,個人認(rèn)為寫代碼的過程其實(shí)不難,難的是思維方式的轉(zhuǎn)換,希望能從文字的描述上給大家一點(diǎn)啟發(fā)。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/97265.html

相關(guān)文章

  • 命令響應(yīng)(六)

    摘要:從這個系列的第一章開始到第五章,基于的響應(yīng)式編程的基礎(chǔ)知識基本上就介紹完了,當(dāng)然有很多知識點(diǎn)沒有提到,比如,等,不是他們不重要,而是礙于時間精力等原因沒辦法一一詳細(xì)介紹。 從這個系列的第一章開始到第五章,基于rxjs的響應(yīng)式編程的基礎(chǔ)知識基本上就介紹完了,當(dāng)然有很多知識點(diǎn)沒有提到,比如 Scheduler, behaviorSubject,replaySubject等,不是他們不重要,...

    sanyang 評論0 收藏0
  • 命令響應(yīng)(七)

    摘要:響應(yīng)式組件上節(jié)中錯誤的把添加到了中,實(shí)際中它返回的是一個,先調(diào)整過來。將這兩條流合并成一條請求流。利用上面實(shí)現(xiàn)的方法,可以很方便的拿到響應(yīng)流,即。由于不同于,請求和響應(yīng)一一對應(yīng)的很好,所以這里可能需要一定的條件來拿到請求對應(yīng)的響應(yīng)。 上回搭建了一個組件以及它所依賴的服務(wù)的基本結(jié)構(gòu),這節(jié)接著它繼續(xù)。另外從本節(jié)開始,統(tǒng)一采用rxjs6的風(fēng)格,6和5在寫法上最大的不同就是棄用鏈?zhǔn)秸{(diào)用,而采用...

    MorePainMoreGain 評論0 收藏0
  • 命令響應(yīng)(八)

    摘要:最近有同學(xué)在使用時總是不能如愿拿到自己想要的數(shù)據(jù),說到底還是沒有能把思維從命令式的習(xí)慣中轉(zhuǎn)換過來。響應(yīng)式的編程風(fēng)格中,數(shù)據(jù)應(yīng)該在流內(nèi)完成轉(zhuǎn)換,合并,過濾,而不是取出來,一頓操作再丟回流里。 最近有同學(xué)在使用rxjs時總是不能如愿拿到自己想要的數(shù)據(jù),說到底還是沒有能把思維從命令式的習(xí)慣中轉(zhuǎn)換過來。 Observable !== 異步 && Observable !== 同步 如題,請默念...

    canger 評論0 收藏0
  • 命令響應(yīng)(三)

    摘要:它有三個方法,用來通知下一個值是什么方法在上產(chǎn)生錯誤時通知觀察者,方法用來通知觀察者當(dāng)前流上的值已經(jīng)發(fā)射完畢。除此之外在我們不需要訂閱時,觀察者還應(yīng)該能夠安全的退出。 上次說了響應(yīng)式中使用的設(shè)計(jì)模式,今天我們主要來看rxjs中實(shí)現(xiàn)響應(yīng)式的三大件,Observable, subject 和 Subscription; Observable--可觀測序列 在第一節(jié)中介紹過 push 類型的...

    k00baa 評論0 收藏0
  • 翻譯連載 | 第 10 章:異步的函數(shù)(下)-《JavaScript輕量級函數(shù)編程》 |《你不知

    摘要:而數(shù)組里則是為每一個值運(yùn)行一次映射函數(shù),無論這個值何時加入,然后把它返回到里。上一章翻譯連載第章異步的函數(shù)式上輕量級函數(shù)式編程你不知道的姊妹篇原創(chuàng)新書移動前端高效開發(fā)實(shí)戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個流淌著滬江血液的純粹工程:認(rèn)真,是 ...

    魏明 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<