如何理解JavaScript中的CSP,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
10年積累的成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有臺(tái)安免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
Communicating Sequential Processes 的 7 個(gè)示例
CSP 是什么? 一般來說, 它是寫并行代碼的一套方案.
在 Go 語言里自帶該功能, Clojure 通過基于 Macro 的 core.async 來實(shí)現(xiàn),
現(xiàn)在 JavaScript 通過 Generator 也能做支持了, 或者說 ES6 的功能.
為什么我要關(guān)心 CSP? 因?yàn)樗鼜?qiáng)大啊, 而且高效, 而且簡(jiǎn)單. 都這樣了你還想要什么? :)
好吧, 說細(xì)節(jié). 怎樣使用呢?我們用 js-csp, 而且需要 generator 支持, ES6 才有.
也就說 Node 4 或者更高的版本才行, 或者瀏覽器代碼用 Babel 編譯一下,
當(dāng)然能其他的編譯工具可能也行, 但你要確認(rèn)下是支持 Generator 的.
Chrome 應(yīng)該是支持 Generator 的.
扯多了, 來看例子吧!
例 1: 進(jìn)程
***個(gè)要學(xué)的概念是"進(jìn)程". 進(jìn)程可以執(zhí)行代碼, 簡(jiǎn)單說就是這樣的了. :)
注: 當(dāng)然不是操作系統(tǒng)原始的進(jìn)程了, js 里模擬的.
這是啟動(dòng)進(jìn)程的語法: generator 函數(shù)作為參數(shù), 傳給 go 函數(shù)執(zhí)行.
import {go} from 'js-csp'; go(function* () { console.log('something!'); }); // terminal output: // // => something!
例 2: 進(jìn)程可以暫停
使用 yield 關(guān)鍵字可以暫停一個(gè)進(jìn)程, 把當(dāng)前進(jìn)程的占用釋放:
import {go, timeout} from 'js-csp'; go(function* () { yield timeout(1000); console.log('something else after 1 second!'); }); console.log('something!'); // terminal output: // // => something! // => something else after 1 second!
例 3: 進(jìn)程等待來自管道的數(shù)據(jù)
第二個(gè)要學(xué)的概念是管道, 也是***一個(gè)了. 管道就像是隊(duì)列.
一旦進(jìn)程對(duì)管道調(diào)用 take, 進(jìn)程就會(huì)暫停, 直到別人往管道放進(jìn)數(shù)據(jù).
import {go, chan, take, putAsync} from 'js-csp'; let ch = chan(); go(function* () { const received = yield take(ch); console.log('RECEIVED:', received); }); const text = 'something'; console.log('SENDING:', text); // use putAsync to put a value in a // channel from outside a process putAsync(ch, text); // terminal output: // // => SENDING: something // => RECEIVED: something
例 4: 進(jìn)程通過管道來通信
管道的另一邊, 往管道里 put 數(shù)據(jù)的那些進(jìn)程也會(huì)暫停, 直到這邊進(jìn)程調(diào)用 take.
下面的例子就復(fù)雜一點(diǎn)了, 試著跟隨一下主線, 印證一下終端輸出的內(nèi)容:
import {go, chan, take, put} from 'js-csp'; let chA = chan(); let chB = chan(); // Process A go(function* () { const receivedFirst = yield take(chA); console.log('A > RECEIVED:', receivedFirst); const sending = 'cat'; console.log('A > SENDING:', sending); yield put(chB, sending); const receivedSecond = yield take(chA); console.log('A > RECEIVED:', receivedSecond); }); // Process B go(function* () { const sendingFirst = 'dog'; console.log('B > SENDING:', sendingFirst); yield put(chA, sendingFirst); const received = yield take(chB); console.log('B > RECEIVED:', received); const sendingSecond = 'another dog'; console.log('B > SENDING:', sendingSecond); yield put(chA, sendingSecond); }); // terminal output: // // => B > SENDING: dog // => A > RECEIVED: dog // => A > SENDING: cat // => B > RECEIVED: cat // => B > SENDING: another dog // => A > RECEIVED: another dog
例5: 管道也是隊(duì)列
由于管道是隊(duì)列, 當(dāng)進(jìn)程從管道取走數(shù)據(jù), 其他進(jìn)程就拿不到了.所以推數(shù)據(jù)的是一個(gè)進(jìn)程, 取數(shù)據(jù)的也是一個(gè)進(jìn)程.
下面這個(gè)例子可以看到第二個(gè)進(jìn)程永遠(yuǎn)不會(huì)打印 B > RECEIVED: dog,
因?yàn)?**個(gè)進(jìn)程已經(jīng)把數(shù)據(jù)取走了.
import {go, chan, take, put} from 'js-csp'; let ch = chan(); go(function* () { const text = yield take(ch); console.log('A > RECEIVED:', text); }); go(function* () { const text = yield take(ch); console.log('B > RECEIVED:', text); }); go(function* () { const text = 'dog' console.log('C > SENDING:', text); yield put(ch, text); }); // terminal output: // // => C > SENDING: dog // => A > RECEIVED: dog
例 6: 帶緩沖的管道不會(huì)在 put 操作時(shí)阻塞
管道可以帶緩沖, 也就是, 一定數(shù)量之內(nèi)的數(shù)據(jù), 執(zhí)行 put 操作可以避開阻塞.
這個(gè)例子里, 即便沒有其他進(jìn)程調(diào)用 take, 前兩個(gè)寫操作也不會(huì)阻塞進(jìn)程.
不過管道的緩存數(shù)量是 2, 所以第三個(gè)數(shù)據(jù)就阻塞進(jìn)程了, 直到其他進(jìn)程取走數(shù)據(jù).
import {go, chan, put, buffers} from 'js-csp'; let ch = chan(buffers.fixed(2)); go(function* () { yield put(ch, 'value A'); yield put(ch, 'value B'); console.log('I should print!'); yield put(ch, 'value C'); console.log('I should not print!'); }); // terminal output: // // => I should print!
例 7: Dropping And Sliding Buffers
固定大小的緩沖在 N 個(gè)數(shù)據(jù)之后會(huì)阻塞, 初次之外, 還有對(duì)緩沖的 dropping 和 sliding 控制.
緩沖的 dropping 以為著管道可以持有 N 個(gè)數(shù)據(jù).再增加額外的數(shù)據(jù)放進(jìn)管道, 管道就會(huì)將其丟棄.
緩沖的 sliding 也可以持有 N 個(gè)數(shù)據(jù). 不過相對(duì)于直接丟棄新數(shù)據(jù),sliding 緩沖原先的***個(gè)推的數(shù)據(jù)會(huì)被丟棄, buffer 里會(huì)留下新的這個(gè)數(shù)據(jù).
下面這個(gè)例子, value B 和 value C 在 dropping 緩沖里被丟棄, 因?yàn)橐呀?jīng)有 value A 了.
第二個(gè)進(jìn)程里, 當(dāng) value B 被放進(jìn)管道, value A 就被丟棄了.
然后 value C 放進(jìn)管道, value B 就被丟棄.
根據(jù)它們的工作原理, dropping 和 sliding 的緩沖永遠(yuǎn)不會(huì)阻塞!
let droppingCh = chan(buffers.dropping(1)); let slidingCh = chan(buffers.sliding(1)); go(function* () { yield put(droppingCh, 'value A'); yield put(droppingCh, 'value B'); yield put(droppingCh, 'value C'); console.log('DROPPING:', yield take(droppingCh)); }); go(function* () { yield put(slidingCh, 'value A'); yield put(slidingCh, 'value B'); yield put(slidingCh, 'value C'); console.log('SLIDING:', yield take(slidingCh)); }); // terminal output: // // => DROPPING: value A // => SLIDING: value C
CSP 用了一段時(shí)間之后, 用回調(diào)或者 Promise 寫代碼就像是侏羅紀(jì)的技術(shù).
我希望 ES6 的 Generator 能幫助 CSP 成為 JavaScript 的一個(gè)標(biāo)準(zhǔn),
就像是 Go 已經(jīng)是的那樣, 以及 Clojure 里正在成為的那樣.
另外有兩個(gè)模型也還有意思, 大概可以認(rèn)為是比 CSP 層級(jí)更高一點(diǎn)的:
函數(shù)式也是響應(yīng)式編程(Rx)跟 Actors, 分別在 Rx 和 Erlang 里用到.
我同時(shí)相信 CSP 對(duì)于前端框架來說非常棒.
關(guān)于如何理解JavaScript中的CSP問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
網(wǎng)頁標(biāo)題:如何理解JavaScript中的CSP
鏈接URL:http://jinyejixie.com/article34/gpggse.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、動(dòng)態(tài)網(wǎng)站、小程序開發(fā)、App設(shè)計(jì)、電子商務(wù)、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)