摘要:最近在學(xué)習(xí),它是使用的響應(yīng)式編程的庫,它使編寫異步或基于回調(diào)的代碼更容易。返回的是一個對于指定的。發(fā)送請求使用了,雖然了多次,但是僅發(fā)送一次請求,了結(jié)果。中有一些操作符可以讓監(jiān)聽強制為異步的方式,例如。
最近在學(xué)習(xí)RxJS,它是使用 Observables 的響應(yīng)式編程的庫,它使編寫異步或基于回調(diào)的代碼更容易。
下面主要介紹Observables 與 promise的不同點。
單值與多值const numberPromise = new Promise((resolve) => { resolve(5); resolve(10) }); numberPromise.then(value => console.log(value)); // 輸出 只會有 5
下面改寫為observables的寫法,使用 next 替代 promise 的 resolve, 用subscribe 取代then來訂閱結(jié)果。
const Observable = require("rxjs/Observable").Observable; const numberObservable = new Observable((observer) => { observer.next(5); observer.next(10); }); numberObservable.subscribe(value => console.log(value)); // 輸出 5 10
observable是可以連續(xù)訂閱的,這個和promise的區(qū)別很大。平時我們遇到的可能大多數(shù)都是一個請求一個響應(yīng)的這種情況,但是我們也會存在一些情況:
setInterval,需要resolve多個值
webSockets
DOM events
const numberObservable = new Observable((observer) => {
let i = 0;
setInterval(() => {
observer.next(i++);
}, 1000);
});
numberObservable.subscribe(value => console.log(value));
// 輸出 0 1 2 3 4 5
代碼執(zhí)行順序
const promise = new Promise((resolve) => { console.log("promise call") resolve(1); console.log("promise end") }) // 執(zhí)行這段代碼 promise call 和 promise end 會立即執(zhí)行 const observable = new Observable(() => { console.log("I was called!"); }); // 此時并沒有console // 只有 observable.subscribe(); 這個時候 I was called!才會被打印出來。
上面兩段代碼就對比可以發(fā)現(xiàn)Observables是lazy的,只有當有人去訂閱(subscribe)的時候Observables才會真正的被執(zhí)行。
如果上方setInterval的函數(shù)寫在promise里面,但是沒有promise.then之類的函數(shù)就會造成資源的浪費,而在observable里面,不訂閱連內(nèi)存都不會分配。
不能取消 & 能取消promise默認是不能取消的,可以使用promise的實現(xiàn)庫 bluebird 來實現(xiàn)。bluebird是完全兼容promise并且添加了一些有用的方法。
const Observable = require("rxjs/Observable").Observable; const observable = new Observable((observer) => { let i = 0; const token = setInterval(() => { observer.next(i++); }, 1000); return () => clearInterval(token); }); const subscription = observable.subscribe(value => console.log(value + "!")); setTimeout(() => { subscription.unsubscribe(); }, 5000) // 結(jié)果 0! 1! 2! 3!
這個地方需要注意的是, subscribe 返回的不是一個Observable! 這就是說不能和promise一樣鏈式的subscribe。subscribe返回的是一個對于指定observable的 Subscription。他只有一個方法可以調(diào)用,就是unsubscribe。
單個訂閱&多個訂閱promise 是比較激進的,在一個promise被創(chuàng)建的時候,他就已經(jīng)執(zhí)行了,并且不能重復(fù)的被執(zhí)行了。
let time; const waitOneSecondPromise = new Promise((resolve) => { console.log("promise call") time = new Date().getTime(); setTimeout(() => resolve("hello world"), 1000); }); waitOneSecondPromise.then((value) => {console.log( "第一次", value, new Date().getTime() - time)}); setTimeout(() => { waitOneSecondPromise.then((value) => {console.log("第二次", value, new Date().getTime() - time)}); }, 5000) // 輸出結(jié)果是 promise call 第一次 hello world 1007 第二次 hello world 5006
上面這個例子中,我創(chuàng)建了一個promise,他是立即執(zhí)行的setTimeout,所以在第一個then函數(shù)中打印時間間隔是約等于 1s,這個是符合我們預(yù)期的,希望能在1s后獲取到promise的返回值 。 第二個then函數(shù)是在 5s之后執(zhí)行的,第二次hello word 和promise的開始時間差約為5s。因為在該promise創(chuàng)建的1s后已經(jīng)resolve,此時就直接調(diào)用then函數(shù),不會延時1s執(zhí)行。因為promise是只會執(zhí)行一次。
那么再來看obsrvables
const Observable = require("rxjs/Observable").Observable; let time; const waitOneSecondObservable = new Observable((observer) => { console.log("I was called"); time = new Date().getTime(); setTimeout(() => observer.next("hey girl"), 1000); }); waitOneSecondObservable.subscribe((value) => {console.log( "第一次", value, new Date().getTime() - time)}); setTimeout(() => { waitOneSecondObservable.subscribe((value) => {console.log( "第二次", value, new Date().getTime() - time)}); }, 5000) // 輸出 I was called 第一次 hey girl 1003 I was called 第二次 hey girl 1003
這個就是我們希望的結(jié)果,他在每一次訂閱的時候都會重新去執(zhí)行被監(jiān)聽的函數(shù),不論什么時候想要用這個函數(shù),只需要重新 subscribe 一下就可以。
用observable已經(jīng)可以實現(xiàn)多次訂閱,但是這有時候可能不能符合我們的業(yè)務(wù)場景,在http請求中,我們可能希望只發(fā)一次請求,但是結(jié)果被多個訂閱者共用。 Observables 本身沒有提供這個功能,我們可以用 RxJS 這個庫來實現(xiàn),它有一個 share 的 operator。
const waitOneSecondObservable = new Observable((observer) => { // 發(fā)送http請求 }); const sharedWaitOneSecondObservable = waitOneSecondObservable.share(); sharedWaitOneSecondObservable.subscribe(doSomething); sharedWaitOneSecondObservable.subscribe(doSomethingElse); // 使用了share,雖然subscribe了多次,但是僅發(fā)送一次請求,share了結(jié)果。一直是異步 & 可能是異步
const promise = new Promise((resolve) => { resolve(5); }); promise.then(value => console.log(value + "!")); console.log("And now we are here."); // And now we are here. 5!
雖然在promise里面 resolve了一個同步的東西,但他還是會先執(zhí)行完代碼。
const Observable = require("rxjs/Observable").Observable; const observable = new Observable((observer) => { // observer.next(5); setTimeout(() => { observer.next(5); }) }); observable.subscribe(value => console.log(value + "!")); console.log("And now we are here."); // 這個如果是直接next 5,則輸出是 5! -> And now we are here. 采用setTimeout next 5, 則相反 And now we are here.-> 5!
promise一直是異步, Observables則比較靈活,是否為異步得根據(jù)自己的函數(shù)來定,這點也比較危險。rxjs中有一些操作符可以讓監(jiān)聽強制為異步的方式,例如 observeOn。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/7261.html
摘要:原文可觀察量是一種能惰性推送的集合,他可以包含多個值。是一種惰性計算方式,會在迭代中同步的返回到無限個可能的話返回值。使用一種處理方法,最終可能會或可能不會返回一個值。無論是同步方式還是異步方式,都可以擇其一來傳遞返回值。 原文:http://reactivex.io/rxjs/manu... Observable 可觀察量是一種能惰性推送的集合,他可以包含多個值。下面的表格對比了推送...
摘要:接下來,我們將實現(xiàn)一個真實的應(yīng)用程序,顯示幾乎實時發(fā)生的地震。得到的由表示,其中包含和的合并元素。如果不同同時傳出元素,合并序列中這些元素的順序是隨機的。是操作序列的強大操作符。但是的方法仍在運行,表明取消并不會取消關(guān)聯(lián)的。 Rxjs 響應(yīng)式編程-第一章:響應(yīng)式Rxjs 響應(yīng)式編程-第二章:序列的深入研究Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整...
摘要:是的縮寫,起源于,是一個基于可觀測數(shù)據(jù)流結(jié)合觀察者模式和迭代器模式的一種異步編程的應(yīng)用庫。是基于觀察者模式和迭代器模式以函數(shù)式編程思維來實現(xiàn)的。學(xué)習(xí)之前我們需要先了解觀察者模式和迭代器模式,還要對流的概念有所認識。 RxJS 是 Reactive Extensions for JavaScript 的縮寫,起源于 Reactive Extensions,是一個基于可觀測數(shù)據(jù)流 Stre...
摘要:響應(yīng)式編程具有很強的表現(xiàn)力,舉個例子來說,限制鼠標重復(fù)點擊的例子。在響應(yīng)式編程中,我把鼠標點擊事件作為一個我們可以查詢和操作的持續(xù)的流事件。這在響應(yīng)式編程中尤其重要,因為我們隨著時間變換會產(chǎn)生很多狀態(tài)片段。迭代器模式的另一主要部分來自模式。 Rxjs 響應(yīng)式編程-第一章:響應(yīng)式Rxjs 響應(yīng)式編程-第二章:序列的深入研究Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序Rxjs 響應(yīng)式編程-...
摘要:而數(shù)組里則是為每一個值運行一次映射函數(shù),無論這個值何時加入,然后把它返回到里。上一章翻譯連載第章異步的函數(shù)式上輕量級函數(shù)式編程你不知道的姊妹篇原創(chuàng)新書移動前端高效開發(fā)實戰(zhàn)已在亞馬遜京東當當開售。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson-《You-Dont-Know-JS》作者 關(guān)于譯者:這是一個流淌著滬江血液的純粹工程:認真,是 ...
閱讀 2621·2021-11-16 11:40
閱讀 3417·2021-11-08 13:26
閱讀 886·2021-10-28 09:32
閱讀 3542·2021-09-13 10:26
閱讀 815·2019-08-30 15:55
閱讀 788·2019-08-30 15:44
閱讀 1917·2019-08-30 15:44
閱讀 1762·2019-08-30 13:48