千家信息网

如何理解JavaScript中的CSP

发表于:2025-11-15 作者:千家信息网编辑
千家信息网最后更新 2025年11月15日,如何理解JavaScript中的CSP,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Communicating Sequential
千家信息网最后更新 2025年11月15日如何理解JavaScript中的CSP

如何理解JavaScript中的CSP,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

Communicating Sequential Processes 的 7 个示例

CSP 是什么? 一般来说, 它是写并行代码的一套方案.

在 Go 语言里自带该功能, Clojure 通过基于 Macro 的 core.async 来实现,

现在 JavaScript 通过 Generator 也能做支持了, 或者说 ES6 的功能.

为什么我要关心 CSP? 因为它强大啊, 而且高效, 而且简单. 都这样了你还想要什么? :)

好吧, 说细节. 怎样使用呢?我们用 js-csp, 而且需要 generator 支持, ES6 才有.

也就说 Node 4 或者更高的版本才行, 或者浏览器代码用 Babel 编译一下,

当然能其他的编译工具可能也行, 但你要确认下是支持 Generator 的.

Chrome 应该是支持 Generator 的.

扯多了, 来看例子吧!

例 1: 进程

***个要学的概念是"进程". 进程可以执行代码, 简单说就是这样的了. :)

注: 当然不是操作系统原始的进程了, js 里模拟的.

这是启动进程的语法: generator 函数作为参数, 传给 go 函数执行.

import {go} from 'js-csp';  go(function* () {   console.log('something!'); });  // terminal output: // // => something!

例 2: 进程可以暂停

使用 yield 关键字可以暂停一个进程, 把当前进程的占用释放:

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: 进程等待来自管道的数据

第二个要学的概念是管道, 也是***一个了. 管道就像是队列.

一旦进程对管道调用 take, 进程就会暂停, 直到别人往管道放进数据.

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: 进程通过管道来通信

管道的另一边, 往管道里 put 数据的那些进程也会暂停, 直到这边进程调用 take.

下面的例子就复杂一点了, 试着跟随一下主线, 印证一下终端输出的内容:

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: 管道也是队列

由于管道是队列, 当进程从管道取走数据, 其他进程就拿不到了.所以推数据的是一个进程, 取数据的也是一个进程.

下面这个例子可以看到第二个进程永远不会打印 B > RECEIVED: dog,

因为***个进程已经把数据取走了.

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: 带缓冲的管道不会在 put 操作时阻塞

管道可以带缓冲, 也就是, 一定数量之内的数据, 执行 put 操作可以避开阻塞.

这个例子里, 即便没有其他进程调用 take, 前两个写操作也不会阻塞进程.

不过管道的缓存数量是 2, 所以第三个数据就阻塞进程了, 直到其他进程取走数据.

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 个数据之后会阻塞, 初次之外, 还有对缓冲的 dropping 和 sliding 控制.

缓冲的 dropping 以为着管道可以持有 N 个数据.再增加额外的数据放进管道, 管道就会将其丢弃.

缓冲的 sliding 也可以持有 N 个数据. 不过相对于直接丢弃新数据,sliding 缓冲原先的***个推的数据会被丢弃, buffer 里会留下新的这个数据.

下面这个例子, value B 和 value C 在 dropping 缓冲里被丢弃, 因为已经有 value A 了.

第二个进程里, 当 value B 被放进管道, value A 就被丢弃了.

然后 value C 放进管道, value B 就被丢弃.

根据它们的工作原理, dropping 和 sliding 的缓冲永远不会阻塞!

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 用了一段时间之后, 用回调或者 Promise 写代码就像是侏罗纪的技术.

我希望 ES6 的 Generator 能帮助 CSP 成为 JavaScript 的一个标准,

就像是 Go 已经是的那样, 以及 Clojure 里正在成为的那样.

另外有两个模型也还有意思, 大概可以认为是比 CSP 层级更高一点的:

函数式也是响应式编程(Rx)跟 Actors, 分别在 Rx 和 Erlang 里用到.

我同时相信 CSP 对于前端框架来说非常棒.

关于如何理解JavaScript中的CSP问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

进程 管道 数据 缓冲 阻塞 例子 代码 放进 支持 函数 问题 队列 帮助 两个 内容 功能 数量 更多 概念 编译 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 员工综合收入数据库 石嘴山软件开发公司电话 网络安全设计框架包括 抖音平台软件开发公司 国家网络安全应急体系建设纲要 苏州朗钧网络技术有限公司 设置数据库密码后电脑无线重启 db2怎么关掉数据库日志 数据库产生数据不一致原因 曲沃新田村镇银行网络安全 甘肃联想服务器虚拟化建设 网络安全应急演练总结下载 学的软件开发很难找工作怎么办 服务器主板的频率哪里看 网络技术经济专业 山西君子岛互联网科技有限公司 分布式云存储服务器属于应用 象山游戏软件开发工具 社帝网络安全小组 电子科技大学互联网大赛 新乡格入网络技术有限公司怎么样 铜陵软件开发培训班 外国的网络安全法律法规 短语数据库 设置数据库密码后电脑无线重启 dota2怎么更改服务器 数据库显示null怎么设置 杨凯 华为 网络安全 区别商业数据库 网络安全在我身边漫画
0