04-03 微信群聊天记录整理

#1

工业聚 10:25 render 函数里的 async 是靠 throw promise + did-catch + then -> re-render 实现的,虽然从 pure 的要求改为幂等,不过 re-render 时不只是触发 render 方法。还有 willUpdate, willReceiveProps 等,把 will 开头的生命周期干掉,替换成静态方法,保证 pure,才可以安全 async render

司徒正美 10:27 willUpdate这些实例方法都是在render阶段的

司徒正美 10:27 而像didMount这些在commit阶段

司徒正美 10:28 render阶段的方法必要在轻量化,防止把DFS过程爆掉

司徒正美 10:29 也防止用户在里面做太多事

司徒正美 10:29 因此requestIdleCallback在这里是计时收费的(对任务进行切片)

司徒正美 10:30 都没有看到答案 Vampire 10:32 明天才解答 Heaven 10:34 实时的感觉好一点,hashnode 的 ama 一般是实时的,gh 上的 ama 就无所谓了

工业聚 10:35 这次是试水,学习一下 clojure 社区里的一个玩法。如果效果不好,下次可以尝试其他模式

Chris、 12:16 [].apply(null,...args) 这里出现 [].apply() is not a function 这个问题是?

Chris、 12:17 咨询一下

工业聚 12:18 因为 Array.prototype 里确实没有 apply 这个方法

Chris、 12:21 用typeof [] 是个对象 东东- 12:24 要用array。is吧

:gun: 12:25 没看懂

:gun: 12:25 下一个 舒欣字樂之 Andy 12:43 @Chris 我怀疑你想写 [].concat.apply。apply在Function上面。

工业聚 15:50 突然想到,其实 react, callbag, koa 等组件化和中间件,都是依赖 callback 机制实现的

工业聚 15:50 react 里是把 setState 封装成一个 callback/handler,传递给子组件,执行后重新渲染

工业聚 15:51 callbag 是把 start、next 和 completed 封装成一个 callback(type, sink) 传递给其它 source,调用后互相传递数据和信号

工业聚 15:51 koa 是用 callback 封装一个 next 函数,调用后执行下一个中间件

工业聚 15:52 promise/generator, async/await 也可以看成 callback 机制的几种形态~

工业聚 15:52 与其说这是 callback 机制,不如说其实是高阶函数的几种用途~

工业聚 15:59 如何更好地利用高阶函数,就涉及到函数式里的各色技巧,保持什么交换律、结合律之类的

工业聚 15:59 怎么 wrap/unwrap 一个 container 从里面存取 value/data

工业聚 16:00 怎么推进抽象的层次,如 map 一个 list,map 一个 tree,map 一个 Maybe,到 map 一个可 map 对象 fmap/functor ~

zwhu 16:10 我一直把这些理解成cps

zwhu 16:14 当然我的理解还只是入门阶段…

工业聚 16:17 cps 的全称是? 肖肖 16:17 Cyber-Physical Systems

Jason²⁰¹⁸ 16:19 Communicating sequential processes ?

Jason²⁰¹⁸ 16:19 有点像go 里的channel

Jason²⁰¹⁸ 16:24 不好意思,看错了,原来是cps KpaxQin 16:28 Continues passing style

zwhu 16:29 Continuation Passing Style

工业聚 16:39 https://en.wikipedia.org/wiki/Continuation-passing_style

工业聚 16:39 看了一下,确实有 cps 的味道,不过似乎有些不同

工业聚 16:40 如果 cps 一定要求值的话,前面 js 里 callback 传来传去的场景里,大多不需要 return callback(data)

工业聚 16:41 _.each(list, fn) 应该不属于 cps,只是高阶函数

工业聚 16:43 callbag 也不像 cps,签名是 (type, sink) -> viod

工业聚 16:45 koa-compse 倒有点像

工业聚 16:46 形式上像,不过其实中间件通常也不关心 next 的返回值

工业聚 16:46 当然,这些只是高级语言里的语法糖,或许可以被 cps 等价表达

RunningCoder 16:55 写了一个简单的demo,目前发现如下: 1. 通过react框架接口绑定的handler在input中输入值时,事件触发为keyDown -> change -> keyUp

RunningCoder 16:55 2. 通过react框架接口绑定的hangler在input获焦时点击esc键,事件触发为blur

RunningCoder 16:55 3. 通过ref或getElementBy等获取真实dom后绑定handler,在input中输入值时,事件触发为keyDown -> keyUp

RunningCoder 16:55 4. 通过ref或 getElementBy 等获取真实dom后绑定handler,在input获焦时点击esc键,事件触发为change(在有数值变化时才有) -> blur

RunningCoder 16:55 demo地址为 https://codepen.io/

RunningCoderLee/pen/EERMGX/

RunningCoder 16:55 但是没搞明白原因是什么[捂脸]

RunningCoder 16:56 有没有大神指点一下

zwhu 16:57 这个需要问正美了,专业的

司徒正美 17:00 事件系统这么复杂

司徒正美 17:00 你不想触发blur吗

司徒正美 17:04 觉得你只绑定onChange事件,而加一个onKeyUp事件,如果onKeyUp里面event有esc ,那么手动触发onChange

工业聚 17:05 react 的事件系统是定制过的,保证了在所有浏览器里都保持一致的行为,并且有些行为跟 W3C 的不一致,最典型的就是 input 的 onchange 事件,跟着输入走, W3C 的 onchange 在 blur 前后

司徒正美 17:05 这文档也坑啊

RunningCoder 17:05 我大概找到问题原因了,估计跟我chrome插件有关

司徒正美 17:05 分明是 (prevMegedState, nextProps)=>

RunningCoder 17:06 我在无痕模式下对同一个demo,在react中绑定事件后,按下esc键后的触发事件为 keydown -> keyup,并且input不会失焦

RunningCoder 17:06 这个应该是标准情况,我犹豫安装了部分插件,导致按下esc键后直接失焦了

RunningCoder 17:12 罪魁祸首是vimium这个插件[捂脸]

Janry 20:15 setImmediate(()=>{for(let i = 0;iconsole.log(2)) Promise.resolve().then(()=>{console.log(3)}) 这几行代码为啥在chrome上返回312,在nodejs上返回321呢 L 20:16 正常

Janry 20:19 原因? L 20:20 浏览器定时器慢

zwhu 20:29 你用node的执行方式是?

Saviio 20:40 我没记错的话

Saviio 20:41 你在node 里跑 settimeout() + setImmediate()是有可能得到两种执行顺序的

Saviio 20:43 另外,你那个for 循环是个空循环,也是有可能直接被优化掉的

soda 20:54 官方文档讲得很清楚的,在同一个IO Cycle 里 setImmediate 肯定先执行,否则不确定

Janry 20:54 执行好多次都是321

soda 20:54 浏览器的话也很简单,setTimeout 有 4ms 的最小间隔

Saviio 21:01 两个 event loop 实现都不一样,哪怕真有差异也是正常的

工业聚 21:07 haskell 写着写着,越来越多尖括号。。

chenyong 21:10 说明上手了

zwhu 21:10 这个语法我还没看到…

chenyong 21:10 我就只能玩 thread macro 那种程度的抽象,

chenyong 21:11 applicative 能把我直接绕晕

工业聚 21:12 它们是故意的,本来叫 map,再抽象一层后叫 fmap,然后改为中缀函数后叫

工业聚 21:13 也是一个中缀函数,后面估计还有很多中缀函数,都是用算术符号之类的裹起来

zwhu 21:13 单纯语法来说,还是 lisp 简单…逼着眼睛写都不会错

chenyong 21:13 我记得 map 跟 fmap 类型签名不一样?

chenyong 21:14 如果是动态类型,应该就一个函数了

工业聚 21:15 函数签名不一样,为了适配更多形态,函数前面从确定性的类型,变成参数化的类型

chenyong 21:16 好吧,各种 kind,我已经记不清楚术语了 [捂脸]

工业聚 21:16 我也是。一周不看,相当于之前白看[捂脸]

chenyong 21:17 又放弃了一次 Haskell…

工业聚 21:17 我继续挣扎挣扎~

chenyong 21:20 clojure 好的地方我写逻辑的时候不用去管复杂类型

chenyong 21:30 lisp 里对变量名限制比 Haskell 还少,好玩的可以有

工业聚 21:32 用一个语言创造另一个特定领域语言,叫 DSL。通过约束或者元编程,把一个语言约束在一个子集里,这个子集应该叫什么?比如(asm.js)

工业聚 21:33 我是工业聚,可以来问我任何问题! 有 17 个问题了,提问质量都还不错

工业聚 21:33 目前最喜欢的问题是 @

zwhu 提的

工业聚 21:34 IR 中间表示,应该是 compiler 里的,不像~

工业聚 21:35 想起来了,可以用老道那句:The good part [捂脸]

工业聚 22:21 看到 monad 了,它的两个函数的签名~

工业聚 22:21 Promise.resolvereturn :: a -> m a,把一个 a 变成 m a 类型,即 promise 对象

工业聚 22:22 promise.then(a => a + 1) 还是返回 promise,即 m a 经过一个函数后,变成 m b

工业聚 22:24 一个不同点是,promise.then(fn) 的 fn 不必直接返回 m b 类型,在内部自动 return (fn a),相当于 return Promise.resolve(fn(a))

chenyong 22:36 样子是挺像的,但是毕竟数学上的 law 啊…约束不少

chenyong 22:36 我记得在群里吵过 promise 到底是不是 monad,搞到最后我也没听明白… fri3nds .

梓寒 22:37 看样子算是

chenyong 22:37 数学上的事情,不用数学语言说不清的

工业聚 23:15 可以单独把签名提出来,不用关心实现的细节

工业聚 23:15 就看类型之间的映射关系

工业聚 23:15 很有趣。类型标注独占一行的好处,也有体现

工业聚 23:16 functor 的 fmap 签名

工业聚 23:17 有个 a -> b 函数,可以把 f a 类型,映射为 f b 类型

工业聚 23:17 map(n => n + 1)([1, 2, 3]) // [2, 3, 4] fri3nds .

梓寒 23:18 看了签名 也没有什么用啊 fri3nds .

梓寒 23:18 haskell 还是得去看源码

工业聚 23:18 Applicative 的 签名~

工业聚 23:19 这个要看什么场景了,如果只是想了解一下参数结构,类型签名信息量足够了~ fri3nds .

梓寒 23:20 那你去问问写haskell 的

工业聚 23:21 我看到过一些写 Haskell 的人,表达类型签名的信息量丰富,了解一个 library,看各个 api 的类型签名,就可以掌握大概,开始使用云云

工业聚 23:22 只有很差的设计或者实现,需要开发者仔细阅读源码去掌握

工业聚 23:23 可复用的意义所在,就是大部分场景不需要去看源码

工业聚 23:23 通过文档、类型声明等线索,就可以干活儿

工业聚 23:27 特别是像 Finger Tree 这类抽象和实现都相对复杂的,如非必要,看源码真心吃力不讨好 fri3nds .

梓寒 23:27 可复用的意义所在,就是大部分场景不需要去看源码 fri3nds .

梓寒 23:28 前面半句是对的 fri3nds .

梓寒 23:28 后面半句除了标点符号是对的 Janry 23:49 函数式编程,没有类型标注就等于害人