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