#并发,core.async 和 JavaScript .footnote[http://git.io/js-csp]
layout: false
-
什么是并发
-
什么是CSP
-
Clojure 是怎么做的
-
为什么要这么做
-
JavaScript又该怎么做
???
这次session主要cover这些内容
所以如果你都没兴趣, 现在离开还来得及
这次session只有一个非常简单的例子, 我希望大家都能看懂, 哪里不懂的请及时打断我
每样东西火起来都是有原因的
当然Go不只是因为前面那个原因火的.
-
Go 使用非常特别的并发模型, 它实现了CSP并发编程, 并且起名叫 goroutines and channels,
-
由于实在是太好用了, Clojure 也加入了CSP的阵营, 叫做 Core.async.
???
前段时间翻了一本叫函数式JavaScript的书, 书其实写的一般, 但有意思的是 作者同时也是 joy of clojure 的作者 Michael Fogus
他contribe过 underscore-contrib 以及 clojure
书中确实有一些东西来自clojure,但是不太多, 但是脑洞顿时被打开
似乎可以把其他语言好的东西搬到javascript, 要迁移就迁移个大的
如果我正在上班写代码,想加个班然后发个短信给老婆说晚点回, 发完以后继续敲代码. 那么发短信和敲代码两个任务就是 并发.
但如果我还特别喜欢音乐, 所以我边听音乐边敲代码, 那么交代吗和听音乐两个任务就是并行了.
???
解释并发与并行实在太简单不过了
继续敲代码这个例子
??? 但是一般说到并发, 可能大家第一反应应该是多线程
比如 <-
template: inverse
我就要fork这么多手
跟多线程对应的是单线程(或一定数量的线程)的异步并发模型,比如JS的Event loop
-
比如我还是两只手, 我正在写代码
-
这时来了条短信
-
我拿起手机看短信, 老婆叫早点回家
-
不鸟, 放下手机继续敲代码.
注意这段动作与之前多线程的区别, 多线程的场景是我fork了第三只手, 而那只手在我敲代码是一直握着手机, 等着读短信.
.left-column[
.left-column[
] .right-column[
猜猜这段代码的输出是啥
JS Bin ]
.left-column[
] .right-column[
- low level
- 阻塞
- 开销大
- 效率低
- 不可预知
- 锁
- 难学
- 难写
- 难测
- 难修
.left-column[
] .right-column[
??? 所以总的来说, 异步还是比多线程要好些, 毕竟level要高一些
template: inverse
??? 于是CSP就来拯救你从callback hell中
-
通信顺序进程, 是计算机科学中用于一种描述并发系统中交互的形式语言, 简称CSP
-
来源于C.A.R Hoare 1978年的论文.
-
没错了, Hoare就是发明
让我们算法课纠结得快挂科的快排算法的那个家伙那位大牛.
??? 回转寿司
CSP 的概念非常简单, 想象一下 event loop
- CSP 把这个event loop的消息队列转换成一个数据队列, 把这个队列叫做 channel
- 所有的任务等待对应队列中的数据
这样就成功的把任务成功从 callback hell 分离开来.
等等, 还是刚才发短信的例子, 我们来用CSP实现一遍
template: inverse
.footnote[如果你不喜欢括号, go的csp例子可以看看12年的golang talk]
(def working (chan))
(def texting (chan))
(defn boss-yelling []
(go-loop [no 1]
(<! (timeout 1000))
(>! working (str "bose say: work " no))
(recur (+ no 1))))
(defn wife-texting []
(go-loop []
(<! (timeout 4000))
(>! texting "wife say: come home!")
(recur)))
(defn reading-text []
(go-loop []
(println (<! texting) "me: ignore")
(recur)))
(defn work []
(go-loop []
(println (<! working) " me: working")
(recur)))
(boss-yelling)
(wife-texting)
(work)
(reading-text)
不懂clojure没有关系,我可以解释,~~我不听我不听我不听!~~而且我还会在后面用JS实现一遍
???
- 单线程
- 同步的编程方式
- 消除了callback
- 并发任务分离
- 好测
- 好改
- Before
askWife1(function(response1){
if(response1)
askWife2(function(response2){
if(response2)
askWife3(function(response3){
if(response3)
working();
})
})
})
- After
(defn work []
(go-loop []
(askWifes)
(when-let [response1 (<! wife1)
response2 (<! wife2)
response3 (<! wife3)]
(println (<! working) " me: working"))
(recur)))
仅仅需要两个东西
-
es6 generator
-
一个简单的状态机
???
.left-column[
] .right-column[
var Gen = function*() {
yield 1;
yield 2;
yield 3;
}
var gen = Gen()
gen.next()
// => Object { value: 1, done: false }
gen.next()
// => Object { value: 2, done: false }
gen.next()
// => Object { value: 3, done: false }
gen.next()
// => Object { value: undefined, done: true }
??? yield不是 ruby 的 yield, 是 python 的yield
-
goroutines
-
timeout
-
take (<!)
-
put (>!)
function take(chan) {
return function() {
if(chan.length === 0) {
return ["park", null];
} else {
var val = chan.pop();
return ["continue", val];
}
};
}
function go_(machine, step) {
while(!step.done) {
var arr = step.value(),
state = arr[0],
value = arr[1];
switch (state) {
case "park":
setTimeout(function() { go_(machine, step); },0);
return;
case "continue":
step = machine.next(value);
break;
}
}
}
function go(machine) {
var gen = machine(); (ref:generator)
go_(gen, gen.next());
}
???
- 一个函数
- 他可以接受一个 generator
- 如果generator没有下一步,则结束
- 如果该步的返回值状态为 park, 那么就是什么也不做, 过一会再来进入状态机尝试
- 如果为 continue, 这接着generator下一步, 继续循环
async function textingWifes(){
var response1 = await askWife1();
var response2 = await askWife2();
var response3 = await askWife3();
if (response1 && response2 && response3)
working();
}
- http://blog.oyanglul.us/javascript/clojure-core.async-essence-in-native-javascript.html
- http://swannodette.github.io/2013/08/24/es6-generators-and-csp/
- http://talks.golang.org/2012/concurrency.slide
- CSP
- Clojure Reactive Programming
- https://github.com/ubolonton/js-csp
- http://wiki.ecmascript.org/doku.php?id=strawman:async_functions
- http://taskjs.org/
- http://sweetjs.org/
name: last-page template: inverse
Slideshow hosted on gistdeck.
你好,文章很棒,内容里面有类似这种
.left-column[
CSS 的东西,是因为使用了什么 md 不支持的东西么?