摘要:響應(yīng)式編程第一章響應(yīng)式響應(yīng)式編程第二章序列的深入研究響應(yīng)式編程第三章構(gòu)建并發(fā)程序響應(yīng)式編程第四章構(gòu)建完整的應(yīng)用程序響應(yīng)式編程第五章使用管理時間響應(yīng)式編程第六章使用的響應(yīng)式應(yīng)用程序使用管理時間自從接觸,就開始在我的項(xiàng)目中使用它。
Rxjs 響應(yīng)式編程-第一章:響應(yīng)式
Rxjs 響應(yīng)式編程-第二章:序列的深入研究
Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序
Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的Web應(yīng)用程序
Rxjs 響應(yīng)式編程-第五章 使用Schedulers管理時間
Rxjs 響應(yīng)式編程-第六章 使用Cycle.js的響應(yīng)式Web應(yīng)用程序
自從接觸RxJS,就開始在我的項(xiàng)目中使用它。有一段時間我以為我知道如何有效地使用它,但有一個令人煩惱的問題:我怎么知道我使用的運(yùn)算符是同步還是異步?換句話說,Operators到底什么時候發(fā)出通知?這似乎是正確使用RxJS的關(guān)鍵部分,但對我來說感覺有點(diǎn)模糊。
我認(rèn)為,間隔運(yùn)算符顯然是異步的,所以它在內(nèi)部使用類似setTimeout的東西來發(fā)出項(xiàng)目。但是,如果我使用范圍怎么辦?它也是異步發(fā)射的嗎?它會阻止事件循環(huán)嗎?來自哪里?我到處都在使用這些運(yùn)算符,但我對它們的內(nèi)部并發(fā)模型知之甚少。
然后我了解了Schedulers。
Schedulers是一種強(qiáng)大的機(jī)制,可以精確管理應(yīng)用程序中的并發(fā)性。它們允許您隨時更改其并發(fā)模型,從而對Observable如何發(fā)出通知進(jìn)行細(xì)粒度控制。在本章中,您將學(xué)習(xí)如何使用調(diào)度程序并在常見場景中應(yīng)用它們。我們將專注于測試,調(diào)度程序特別有用,您將學(xué)習(xí)如何制作自己的Schedulers。
使用SchedulersSchedulers是一種“安排”將來發(fā)生的操作的機(jī)制。 RxJS中的每個運(yùn)算符在內(nèi)部使用一個Schedulers,選擇該Schedulers以在最可能的情況下提供最佳性能。
讓我們看看我們?nèi)绾胃淖冞\(yùn)算符中的Schedulers以及這樣做的后果。 首先讓我們創(chuàng)建一個包含1,000個整數(shù)的數(shù)組:
var arr = [];
for (var i=0; i<1000; i++) {
arr.push(i);
}
然后,我們從arr創(chuàng)建一個Observable并強(qiáng)制它通過訂閱它來發(fā)出所有通知。 在代碼中,我們還保存了發(fā)出所有通知所需的時間:
var timeStart = Date.now();
Rx.Observable.from(arr).subscribe(
function onNext() {},
function onError() {},
function onCompleted() {
console.log("Total time: " + (Date.now() - timeStart) + "ms");
}
);
"Total time: 6ms”
六毫秒 - 不壞! from在內(nèi)部使用Rx.Scheduler.currentThread,它計(jì)劃在任何當(dāng)前工作完成后運(yùn)行。 一旦啟動,它將同步處理所有通知。
在讓我們將Scheduler更改為Rx.Scheduler.default
var timeStart = Date.now();
Rx.Observable.from(arr, null, null, Rx.Scheduler.default).subscribe(
function onNext() {},
function onError() {},
function onCompleted() {
console.log("Total time: " + (Date.now() - timeStart) + "ms");
}
);
"Total time: 5337ms”
哇,我們的代碼運(yùn)行速度比使用currentThread Scheduler慢幾千倍。 那是因?yàn)槟J(rèn)的Scheduler異步運(yùn)行每個通知。 我們可以通過在訂閱后添加一個簡單的日志語句來驗(yàn)證這一點(diǎn)。
使用currentThread Scheduler:
Rx.Observable.from(arr).subscribe( ... );
console.log("Hi there!’);
"Total time: 8ms" "Hi there!"
使用默認(rèn)Scheduler:
Rx.Observable.from(arr, null, null, Rx.Scheduler.timeout).subscribe( ... );
console.log("Hi there!’);
"Hi there!" "Total time: 5423ms"
因?yàn)槭褂媚J(rèn)Schedule的Observer以異步方式發(fā)出其項(xiàng)目,所以我們的console.log語句(它是同步的)在Observable甚至開始發(fā)出任何通知之前執(zhí)行。 使用currentThread Scheduler,所有通知都會同步發(fā)生,因此只有在Observable發(fā)出所有通知時才會執(zhí)行console.log語句。
因此,Scheduler確實(shí)可以改變我們的Observable的工作方式。 在我們的例子中,性能確實(shí)受到異步處理一個已經(jīng)可用的大型陣列的影響。 但我們實(shí)際上可以使用Scheduler來提高性能。 例如,我們可以在對Observable執(zhí)行昂貴的操作之前動態(tài)切換Scheduler:
arr.groupBy(function(value) {
return value % 2 === 0;
})
.map(function(value) {
return value.observeOn(Rx.Scheduler.default);
})
.map(function(groupedObservable) {
return expensiveOperation(groupedObservable);
});
在前面的代碼中,我們將數(shù)組中的所有值分為兩組:偶數(shù)和非偶數(shù)。 groupBy返回一個Observable,它為每個創(chuàng)建的組發(fā)出一個Observable。 這里是很酷的部分:在運(yùn)行之前對每個分組的Observable中的項(xiàng)目進(jìn)行昂貴的操作,我們使用observeOn將Scheduler切換到默認(rèn)值,這樣昂貴的操作將異步執(zhí)行,而不是阻塞事件循環(huán)
observeOn和subscribeOn在上一節(jié)中,我們使用observeOn運(yùn)算符來更改某些Observable中的Scheduler。 observeOn和subscribeOn是返回Observable實(shí)例副本的運(yùn)算符,但它使用的Scheduler我們作為參數(shù)傳遞的。
observeOn接受一個Scheduler并返回一個使用該Scheduler的新Observable。 它將使每個onNext調(diào)用在新的Scheduler中運(yùn)行。
subscribeOn強(qiáng)制Observable的訂閱和取消訂閱工作(而不是通知)在特定的Scheduler上運(yùn)行。 與observeOn一樣,它接受Scheduler作為參數(shù)。 例如,當(dāng)我們在瀏覽器中運(yùn)行并在訂閱調(diào)用中執(zhí)行重要工作時,卻不希望用它來阻止UI線程,subscribeOn非常有用。
基本的Rx Scheduler讓我們在我們剛剛使用的Scheduler中深入了解一下。 RxJS的運(yùn)算符最常用的是immediate,default和currentThread。
Immediate SchedulerImmediate Scheduler同步發(fā)出來自O(shè)bservable的通知,因此無論何時在Immediate Scheduler上調(diào)度操作,它都將立即執(zhí)行,從而阻塞該線程。 Rx.Observable.range是內(nèi)部使用Immediate Scheduler序的運(yùn)算符之一:
console.log("Before subscription");
Rx.Observable.range(1, 5)
.do(function(a) {
console.log("Processing value", a);
})
.map(function(value) { return value * value; })
.subscribe(function(value) { console.log("Emitted", value); });
console.log("After subscription");
Before subscription Processing value 1 Emitted 1 Processing value 2 Emitted 4 Processing value 3 Emitted 9 Processing value 4 Emitted 16 Processing value 5 Emitted 25 After subscription
程序輸出按我們期望的順序發(fā)生。 每個console.log語句在當(dāng)前項(xiàng)的通知之前運(yùn)行。
何時使用它Immediate Scheduler非常適合于在每個通知中執(zhí)行可預(yù)測且非常昂貴的操作的Observable。 此外,Observable最終必須調(diào)用onCompleted。
Default SchedulerDefault Scheduler以異步方式運(yùn)行操作。 您可以將其視為setTimeout的等價物,其延遲為零毫秒,從而保持序列中的順序。 它使用其運(yùn)行的平臺上可用的最有效的異步實(shí)現(xiàn)(例如,Node.js中的process.nextTick或?yàn)g覽器中的setTimeout)。
讓我們使用前一個使用了range示例,并使其在默認(rèn)的Scheduler上運(yùn)行。 為此,我們將使用observeOn運(yùn)算符:
console.log("Before subscription");
Rx.Observable.range(1, 5)
.do(function(value) {
console.log("Processing value", value);
})
.observeOn(Rx.Scheduler.default)
.map(function(value) { return value * value; })
.subscribe(function(value) { console.log("Emitted", value); });
console.log("After subscription");
Before subscription Processing value 1 Processing value 2 Processing value 3 Processing value 4 Processing value 5 After subscription Emitted 1 Emitted 4 Emitted 9 Emitted 16 Emitted 25
這個輸出有很大的不同。 我們的同步console.log語句輸出每個值,但我們使Observable在默認(rèn)的Scheduler上運(yùn)行,它會異步生成每個值。 這意味著我們在do運(yùn)算符中的日志語句在平方值之前處理。
何時使用它Default Scheduler永遠(yuǎn)不會阻塞事件循環(huán),因此它非常適合涉及時間的操作,如異步請求。 它也可以在從未完成的Observable中使用,因?yàn)樗粫诘却峦ㄖ獣r阻塞程序(這可能永遠(yuǎn)不會發(fā)生)。
Current Thread SchedulercurrentThread Scheduler與Immediate Scheduler一樣是同步的,但是如果我們使用遞歸運(yùn)算符,它會將要執(zhí)行的操作排入隊(duì)列,而不是立即執(zhí)行它們。 遞歸運(yùn)算符是一個自己調(diào)度另一個運(yùn)算符的運(yùn)算符。 一個很好的例子就是repeat。 repeat運(yùn)算符 - 如果沒有給出參數(shù) - 將無限期地重復(fù)鏈中的先前Observable序列。
如果對使用Immediate Scheduler的運(yùn)算符(例如return)調(diào)用repeat,則會遇到麻煩。 讓我們通過重復(fù)值10來嘗試這個,然后使用take只取重復(fù)的第一個值。 理想情況下,代碼將打印10次然后退出:
// Be careful: the code below will freeze your environment!
Rx.Observable.return(10).repeat().take(1)
.subscribe(function(value) {
console.log(value);
});
Error: Too much recursion
此代碼導(dǎo)致無限循環(huán)。 在訂閱時,如return調(diào)用onNext(10)然后onCompleted,這使得repeat再次訂閱return。 由于返回正在Immediate Scheduler上運(yùn)行,因此該過程會重復(fù),導(dǎo)致無限循環(huán)并且永遠(yuǎn)不會結(jié)束。
但是如果相反我們通過將它作為第二個參數(shù)傳遞給currentThread Scheduler給return,我們得到:
var scheduler = Rx.Scheduler.currentThread;
Rx.Observable.return(10, scheduler).repeat().take(1)
.subscribe(function(value) {
console.log(value);
});
10
現(xiàn)在,當(dāng)repeat重新訂閱返回時,新的onNext調(diào)用將排隊(duì),因?yàn)橹暗膐nCompleted仍在發(fā)生。 repeat然后返回一個可以使用的一次性對象,它調(diào)用onCompleted并通過重復(fù)處理取消repeat,最終從subscribe返回調(diào)用。
何時使用它currentThread Scheduler對于涉及遞歸運(yùn)算符(如repeat)的操作非常有用,并且通常用于包含嵌套運(yùn)算符的迭代。
動畫調(diào)度對于諸如canvas或DOM動畫之類的快速視覺更新,我們可以使用具有非常小時間間隔的interval運(yùn)算符,或者我們可以在內(nèi)部使用類似setTimeout的函數(shù)來調(diào)度通知。
但這兩種方法都不理想。 在他們兩個中我們都在瀏覽器上拋出所有這些更新,這可能無法足夠快地處理它們。之所以會發(fā)生這種情況,是因?yàn)闉g覽器正在嘗試渲染一個幀,然后它會收到渲染下一幀的指令,因此它會丟棄當(dāng)前幀以保持速度。 結(jié)果是導(dǎo)致動畫的不流暢,卡頓。
瀏覽器具有處理動畫的原生方式,并且它們提供了一個使用它的API,稱為requestAnimationFrame。 requestAnimationFrame允許瀏覽器通過在最合適的時間排列動畫來優(yōu)化性能,并幫助我們實(shí)現(xiàn)更流暢的動畫。
有專門的Scheduler處理requestAnimationFrameRxDOM庫附帶了一些額外的調(diào)度程序,其中一個是requestAnimationFrame Scheduler。
是的,你猜對了。 我們可以使用此Scheduler來改進(jìn)我們的太空飛船視頻游戲。 在其中,我們建立了40ms的刷新速度 - 大約每秒25幀 - 通過在該速度下創(chuàng)建一個interval Observable,然后使用combineLatest以間隔設(shè)置的速度更新整個游戲場景(因?yàn)樗亲羁焖俑碌腛bservable) )...但誰知道瀏覽器使用這種技術(shù)丟幀了多少幀! 使用requestAnimationFrame可以獲得更好的性能。
讓我們創(chuàng)建一個使用Rx.Scheduler.requestAnimationFrame作為其調(diào)度程序的Observable。 請注意,它與interval運(yùn)算符的工作方式類似:
ch_schedulers/starfield_raf.js
function animationLoop(scheduler) {
return Rx.Observable.generate(
0,
function() { return true; }, // Keep generating forever
function(x) { return x + 1; }, // Increment internal value
function(x) { return x; }, // Value to return on each notification
Rx.Scheduler.requestAnimationFrame
); // Schedule to requestAnimationFrame
}
現(xiàn)在,無論何時我們使用了25 FPS動畫,我們都可以使用animationLoop函數(shù)。 所以我們的Observable繪制了星星,之前看起來像這樣:
spaceship_reactive/spaceship.js
var StarStream = Rx.Observable.range(1, 250)
.map(function() {
return {
x: parseInt(Math.random() * canvas.width),
y: parseInt(Math.random() * canvas.height),
size: Math.random() * 3 + 1
};
})
.toArray()
.flatMap(function(arr) {
return Rx.Observable.interval(SPEED).map(function() {
return arr.map(function(star) {
if (star.y >= canvas.height) {
star.y = 0;
}
star.y += 3;
return star;
});
});
});
變成這樣:
ch_schedulers/starfield_raf.js
var StarStream = Rx.Observable.range(1, 250)
.map(function() {
return {
x: parseInt(Math.random() * canvas.width),
y: parseInt(Math.random() * canvas.height),
size: Math.random() * 3 + 1
};
})
.toArray()
.flatMap(function(arr) {
return animationLoop().map(function() {
return arr.map(function(star) {
if (star.y >= canvas.height) {
star.y = 0;
}
star.y += 3;
return star;
});
});
});
這給了我們一個更流暢的動畫。 代碼也更簡潔!
使用Scheduler進(jìn)行測試測試可能是我們可以使用Scheduler的最引人注目的場景之一。 到目前為止,在本書中,我們一直在編寫我們的核心代碼而不考慮后果。 但是在現(xiàn)實(shí)世界的軟件項(xiàng)目中,我們將編寫測試以確保我們的代碼按照我們的意圖運(yùn)行。
測試異步代碼很難。 我們經(jīng)常遇到以下問題之一:
模擬異步事件很復(fù)雜且容易出錯。 測試的重點(diǎn)是避免bug和錯誤,但如果你的測試本身有錯誤,那這顯然是有問題的。
如果我們想要準(zhǔn)確測試基于時間的功能,自動化測試變得非常緩慢。 例如,如果我們需要準(zhǔn)確測試在嘗試檢索遠(yuǎn)程文件四秒后調(diào)用錯誤,則每個測試至少需要花費(fèi)很長時間才能運(yùn)行結(jié)束。 如果我們不斷運(yùn)行我們的測試套件,那將影響我們的開發(fā)時間。
TestSchedulerRxJS為我們提供了TestScheduler,一個旨在幫助測試的Scheduler。 TestScheduler允許我們在方便時模擬時間并創(chuàng)建確定性測試,確保它們100%可重復(fù)。 除此之外,它允許我們執(zhí)行需要花費(fèi)大量時間并將其壓縮到瞬間的操作,同時保持測試的準(zhǔn)確性。
TestScheduler是VirtualTimeScheduler的專業(yè)化。 VirtualTimeSchedulers在“虛擬”時間而不是實(shí)時執(zhí)行操作。 計(jì)劃的操作進(jìn)入隊(duì)列并在虛擬時間內(nèi)分配一個時刻。 然后,Scheduler在其時鐘前進(jìn)時按順序運(yùn)行操作。 因?yàn)樗翘摂M時間,所以一切都立即運(yùn)行,而不必等待指定的時間。 我們來看一個例子:
var onNext = Rx.ReactiveTest.onNext;
QUnit.test("Test value order", function(assert) {
var scheduler = new Rx.TestScheduler();
var subject = scheduler.createColdObservable(
onNext(100, "first"),
onNext(200, "second"),
onNext(300, "third")
);
var result = "";
subject.subscribe(function(value) { result = value });
scheduler.advanceBy(100);
assert.equal(result, "first");
scheduler.advanceBy(100);
assert.equal(result, "second");
scheduler.advanceBy(100);
assert.equal(result, "third");
});
在前面的代碼中,我們測試了來自冷Observable的一些值以正確的順序到達(dá)。 為此,我們在TestScheduler中使用helper方法createColdObservable來創(chuàng)建一個Observable,它回放我們作為參數(shù)傳遞的onNext通知。 在每個通知中,我們指定應(yīng)該發(fā)出通知值的時間。 在此之后,我們訂閱此Observable,手動提前調(diào)度程序中的虛擬時間,并檢查它是否確實(shí)發(fā)出了預(yù)期值。 如果示例在正常時間運(yùn)行,則需要300毫秒,但由于我們使用TestScheduler來運(yùn)行Observable,它將立即運(yùn)行,但完全按照我們的順序。
寫一個真實(shí)的測試案例沒有比在現(xiàn)實(shí)世界中為時間敏感的任務(wù)編寫測試更好的方法來理解如何使用虛擬時間來縮短時間。 讓我們從我們在緩沖值中制作的地震查看器中恢復(fù)一個Observable:
quakes
.pluck("properties")
.map(makeRow)
.bufferWithTime(500)
.filter(function(rows) { return rows.length > 0; })
.map(function(rows) {
var fragment = document.createDocumentFragment();
rows.forEach(function(row) {
fragment.appendChild(row);
});
return fragment;
})
.subscribe(function(fragment) {
table.appendChild(fragment);
});
為了使代碼更易于測試,讓我們將Observable封裝在一個函數(shù)中,該函數(shù)接受我們在bufferWithTime運(yùn)算符中使用的Scheduler。在Obpectables中參數(shù)化將要測試的Scheduler總是一個好主意。
ch_schedulers/testscheduler.js
function quakeBatches(scheduler) {
return quakes.pluck("properties")
.bufferWithTime(500, null, scheduler || null)
.filter(function(rows) {
return rows.length > 0;
});
}
讓我們通過采取一些步驟來簡化代碼,但保持本質(zhì)。 此代碼采用包含屬性屬性的Observable JSON對象,將它們緩沖到每500毫秒釋放的批次中,并過濾掉空的批次。
我們想要驗(yàn)證此代碼是否有效,但我們絕對不希望每次運(yùn)行測試時都等待幾秒鐘,以確保我們的緩沖按預(yù)期工作。 這是虛擬時間和TestScheduler將幫助我們的地方:
ch_schedulers/testscheduler.js
? var onNext = Rx.ReactiveTest.onNext;
var onCompleted = Rx.ReactiveTest.onCompleted;
var subscribe = Rx.ReactiveTest.subscribe;
? var scheduler = new Rx.TestScheduler();
? var quakes = scheduler.createHotObservable(
onNext(100, { properties: 1 }),
onNext(300, { properties: 2 }),
onNext(550, { properties: 3 }),
onNext(750, { properties: 4 }),
onNext(1000, { properties: 5 }),
onCompleted(1100)
);
? QUnit.test("Test quake buffering", function(assert) {
? var results = scheduler.startScheduler(function() {
return quakeBatches(scheduler)
}, {
created: 0,
subscribed: 0,
disposed: 1200
});
? var messages = results.messages;
console.log(results.scheduler === scheduler);
? assert.equal(
messages[0].toString(),
onNext(501, [1, 2]).toString()
);
assert.equal(
messages[1].toString(),
onNext(1001, [3, 4, 5]).toString()
);
assert.equal(
messages[2].toString(),
onCompleted(1100).toString()
);
});
讓我們一步一步地剖析代碼:
我們首先從ReactiveTest加載一些輔助函數(shù)。 這些在虛擬時間內(nèi)注冊onNext,onCompleted和訂閱事件。
我們創(chuàng)建了一個新的TestScheduler,它將推動整個測試。
我們使用TestScheduler中的方法createHotObservable創(chuàng)建一個假的熱Observable,它將在虛擬時間內(nèi)模擬特定點(diǎn)的通知。 特別是,它在第一秒發(fā)出五個通知,并在1100毫秒完成。 每次它發(fā)出一個具有特定屬性的對象。
我們可以使用任何測試框架來運(yùn)行測試。 對于我們的例子,我選擇了QUnit。
我們使用startScheduler方法創(chuàng)建一個使用測試調(diào)度程序的Observable。 第一個參數(shù)是一個函數(shù),它創(chuàng)建Observable以使用我們的Scheduler運(yùn)行。 在我們的例子中,我們只返回我們傳遞TestScheduler的quakeBatches函數(shù)。 第二個參數(shù)是一個對象,它包含我們想要創(chuàng)建Observable的不同虛擬時間,訂閱它并處理它。 對于我們的示例,我們在虛擬時間0開始和訂閱,并且我們在1200(虛擬)毫秒處理Observable。
startScheduler方法返回一個帶有scheduler和messages屬性的對象。 在消息中,我們可以在虛擬時間內(nèi)找到Observable發(fā)出的所有通知。
我們的第一個斷言測試在501毫秒之后(在第一個緩沖時間限制之后),我們的Observable產(chǎn)生值1和2。
我們的第二個斷言測試在1001毫秒后,我們的Observable產(chǎn)生剩余的值3,4和5.最后,我們的第三個斷言檢查序列是否完全在1100毫秒完成,正如我們在熱的Observable地震中所指出的那樣。
該代碼以非常可靠的方式有效地測試我們的高度異步的Observable,并且無需跳過箍來模擬異步條件。我們只是指定我們希望代碼在虛擬時間內(nèi)作出反應(yīng)的時間,我們使用測試調(diào)度程序來運(yùn)行整個操作。
總結(jié)Scheduler是RxJS的重要組成部分。 即使您可以在沒有明確使用它們的情況下走很長的路,它們也是一種先進(jìn)的概念,它可以讓您在程序中微調(diào)并發(fā)性。虛擬時間的概念是RxJS獨(dú)有的,對于測試異步代碼等任務(wù)非常有用。
在下一章中,我們將使用Cycle.js,這是一種基于稱為單向數(shù)據(jù)流的概念來創(chuàng)建令人驚嘆的Web應(yīng)用程序的反應(yīng)方式。有了它,我們將使用現(xiàn)代技術(shù)創(chuàng)建一個快速的Web應(yīng)用程序,從而顯著改進(jìn)傳統(tǒng)的Web應(yīng)用程序制作方式。
關(guān)注我的微信公眾號,更多優(yōu)質(zhì)文章定時推送
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/108136.html
摘要:由于技術(shù)棧的學(xué)習(xí),筆者需要在原來函數(shù)式編程知識的基礎(chǔ)上,學(xué)習(xí)的使用。筆者在社區(qū)發(fā)現(xiàn)了一個非常高質(zhì)量的響應(yīng)式編程系列教程共篇,從基礎(chǔ)概念到實(shí)際應(yīng)用講解的非常詳細(xì),有大量直觀的大理石圖來輔助理解流的處理,對培養(yǎng)響應(yīng)式編程的思維方式有很大幫助。 showImg(https://segmentfault.com/img/bVus8n); [TOC] 一. 響應(yīng)式編程 響應(yīng)式編程,也稱為流式編程...
摘要:響應(yīng)式編程具有很強(qiáng)的表現(xiàn)力,舉個例子來說,限制鼠標(biāo)重復(fù)點(diǎn)擊的例子。在響應(yīng)式編程中,我把鼠標(biāo)點(diǎn)擊事件作為一個我們可以查詢和操作的持續(xù)的流事件。這在響應(yīng)式編程中尤其重要,因?yàn)槲覀冸S著時間變換會產(chǎn)生很多狀態(tài)片段。迭代器模式的另一主要部分來自模式。 Rxjs 響應(yīng)式編程-第一章:響應(yīng)式Rxjs 響應(yīng)式編程-第二章:序列的深入研究Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序Rxjs 響應(yīng)式編程-...
摘要:原文是一個使用可觀察量隊(duì)列解決異步編程和基于事件編程的庫。提供了幾個管理異步事件的核心概念可觀察量,代表了一個由未來獲取到的值或事件組成的集合。相當(dāng)于事件觸發(fā)器,是向多個廣播事件或推送值的唯一方法。 原文:http://reactivex.io/rxjs/manu... RxJS 是一個使用可觀察量(observable)隊(duì)列解決異步編程和基于事件編程的js庫。他提供了一個核心的類型O...
摘要:補(bǔ)充說明響應(yīng)式編程采用了訂閱觀察者設(shè)計(jì)模式,使訂閱者可以將通知主動發(fā)送給各訂閱者。一個響應(yīng)式編程的實(shí)現(xiàn)庫是一個庫,它通過使用序列來編寫異步和基于事件的程序。 或許響應(yīng)式布局這個名單大家都聽過或者都自己實(shí)現(xiàn)過,那么響應(yīng)式編程是什么呢?下面我們來具體聊一聊。 我的理解 從字面意思上我們可以大致理解為:所有的事件存在于一條事件總線上,所有的事件都可以看作未來某個時間將要發(fā)生的事件流(stre...
摘要:我們將使用,這是一個現(xiàn)代,簡單,漂亮的框架,在內(nèi)部使用并將響應(yīng)式編程概念應(yīng)用于前端編程。驅(qū)動程序采用從我們的應(yīng)用程序發(fā)出數(shù)據(jù)的,它們返回另一個導(dǎo)致副作用的。我們將使用來呈現(xiàn)我們的應(yīng)用程序。僅采用長度超過兩個字符的文本。 Rxjs 響應(yīng)式編程-第一章:響應(yīng)式Rxjs 響應(yīng)式編程-第二章:序列的深入研究Rxjs 響應(yīng)式編程-第三章: 構(gòu)建并發(fā)程序Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的We...
閱讀 4211·2021-11-25 09:43
閱讀 2434·2021-11-23 10:13
閱讀 1070·2021-11-16 11:44
閱讀 2558·2019-08-29 17:24
閱讀 1517·2019-08-29 17:17
閱讀 3621·2019-08-29 11:30
閱讀 2729·2019-08-26 13:23
閱讀 2489·2019-08-26 12:10