AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

core.async: 另一种 Clojure 和 ClojureScript 异步编程方式

  • 2013-07-28
  • 本文字数:1350 字

    阅读完需:约 4 分钟

虽然 core.async Clojure/ClojureScript 库发布还不到一个月,但是与此相关的博客帖子已经发布了很多,它们描述了如何有效地使用 core.async 在前端代码中避免“回调嵌套”,还展示了一些令人印象深刻的浏览器示例的简单代码

core.async 是一个用 Clojure 编写的,Clojure 和 ClojureScript 都能使用的库。Clojure 是一个基于 JVM 的 Lisp 实现。ClojureScript 是 Clojure 的一个子集,它可以将 Clojure 编译成 JavaScript。core.async 很好地呈现了 Lisp 所必须提供的宏机制的能力:很多其他的语言要实现 core.async 所做的事情必须要对语言做出改变,但是在一个 Lisp 中则可以通过使用的库来实现。

正如名字所提示的,core.async 是为了简化异步编程而设计的。它借鉴了 Go 语言的很多思想,特别是它的 goroutine (在 core.async 中称为 go blocks)和通道理念。一个通道是一个有一个或者多个发布者和一个或者多个消费者的队列。它的原理很简单:发布者将数据放到队列中,消费者从队列中获取数据。在 Clojure/ClojureScript 中数据是不可变的,通道提供了一种安全的方式在线程间通信。但是在 ClojureScript 中后者并不是一个特别有趣的特性,因为 JavaScript 是单线程的。

core.async 提供了两种方式向通道写入或者从通道读取数据:阻塞式和非阻塞式。一个阻塞写操作会阻塞线程,直到通道有空间被写入时为止(一个通道的缓冲区大小是可配置的);一个阻塞读操作会阻塞线程,直到队列中的值能够被读取到时为止。更有趣的是,ClojureScript 仅支持异步的通道读取和写入,并且这仅在“go 语句块”中才被允许。Go 语句块是按照同步风格编写的,在内部这些语句块会被转换成一个能够异步执行它们的状态机。

想想下面这段基于 core.async 的代码:

复制代码
(let [ch (chan)]
(go (while true
(let [v (<! ch)]
(println "Read: " v))))
(go (>! ch "hi")
(<! (timeout 5000))
(>! ch "there")))

在这个示例中,let 引入了一个新的局部变量 ch,它是一个新通道。在 let 域中定义了两个 go 语句块,第一个是一个永久循环,它从通道 ch 中读取(<!)一个新的值赋给变量 v。然后它会把“Read:”和读取到的值打印到标准输出。第二个 go 语句块向通道 ch:”hi”中写入(>!)两个值,然后它会等待 5 秒钟再向通道中写入“there”。等待 5 秒钟是通过一个 timeout 通道实现的,该通道会在设置的超时时间过后关闭自己(返回 nil)。在 Clojure REPL 中运行这段代码时,它会立即返回。然后它将打印“Read:hi”,5 秒钟之后它会打印“Read:there”。

无论哪个 JavaScript 程序员,在看到这个 while 循环的时候都会感到怪异:你不能这样实现阻塞循环:浏览器将会冻结 5 秒钟。core.async 的“魔力”在于,它会在内部将每一个 go 语句块的主体部分转换成一个状态机,并且将同步通道的读写转变成异步调用。如果你想获取 core.async 相关的更多信息,或者了解它对前端 Web 开发有什么影响,可以查看下面的资源:

查看英文原文 core.async: A Different Approach to Asynchronous Programming with Clojure and ClojureScript

2013-07-28 03:576121
用户头像

发布了 321 篇内容, 共 124.6 次阅读, 收获喜欢 19 次。

关注

评论

发布
暂无评论
发现更多内容

面试官:你真的了解Redis分布式锁吗?

鄙人薛某

redis 分布式锁 线程安全 RedLock

“反垄断”来袭,对产业区块链有什么启发

CECBC

市场垄断

用AI「驯服」人类幼崽,手头有娃的可以试试

博文视点Broadview

人工智能 联邦学习 强化学习 集成学习 技术宅

为什么我认为 Deno 是一个迈向错误方向的 JavaScript 运行时?

hylerrix

typescript rust nodejs deno V8

区块链十年与传统金融的变化

CECBC

区块链 金融

矿机挖矿APP系统模式开发平台

v16629866266

初识ClickHouse——安装与入门

Simon

Clickhouse

自动量化搬砖套利交易机器人系统软件APP开发

系统开发

一文解析DDD中台和微服务设计

欧创新

中台 微服务 领域驱动设计 DDD

来不及解释!Linux常用命令大全,先收藏再说

华为云开发者联盟

Linux 编程 命令行 命令

生产者与消费者模式,数组阻塞队列(ArrayBlockingQueue)

李尚智

Java 学习 架构 并发编程

DevSecOps安全检查清单

啸天

安全 DevSecOps 应用安全

即构小程序直播组件集成教程

ZEGO即构

不同公司产品经理岗位对比

LouisN

从CPU到XPU进化,英特尔对业界放了什么大招?

E科讯

Volcano架构设计与原理介绍

华为云原生团队

大数据 AI 云原生 高性能 批量计算

敏捷里为何倡导固定迭代周期?

万事ONES

敏捷开发 研发管理 迭代

面试阿里Java岗,技术总监真正关心的核心能力是什么?

Java架构追梦

Java 编程 架构

『CDN』让你的网站访问起来更加柔顺丝滑

古时的风筝

CDN

当音乐学博士搞起编程...

程序猿DD

Spring Frame

「产品经理训练营」第一章作业

Sòrγy_じò ぴé

产品经理训练营

特斯拉自建ERP的背后

明道云

在数据分析、挖掘方面,有哪些ETL工具值得推荐?

敏捷调度TASKCTL

大数据 kettle 海豚调度 批量任务 ETL

Soul 网关源码阅读(二)代码初步运行

Java 源码阅读 网关

架构师训练营第十三周作业

李日盛

PageRank

区块链科普系列:区块链是什么?

CECBC

区块链

架构师训练营W13作业

Geek_f06ede

iOS性能优化 — 五、App启动优化

iOSer

ios 性能优化 性能分析

Soul 网关源码阅读(一) 概览

Java 源码阅读 网关

一文带你探究Sentinel的独特初始化

华为云开发者联盟

redis sentinel 框架

物流快递公司APP架构设计

jorden wang

core.async: 另一种Clojure和ClojureScript异步编程方式_语言 & 开发_Zef Hemel_InfoQ精选文章