我正在为WebSharper创建ampify.js绑定(bind)。 (https://github.com/aph5nt/websharper.amplifyjs)。在测试我的扩展程序时,我发现了发布/订阅实现的一个问题。
我声明了一个订阅处理程序:
let subscribeFn (data:obj) = JS.Alert(data :?> string)
我创建了一个订阅:
Amplify.Amplify.Subscribe("tryPubSub", subscribeFn)
当我想退订时,我会:
Amplify.Amplify.Unsubscribe("tryPubSub", subscribeFn)
问题在于,subscribeFn被转换为两个不同的函数。
如果我调试js代码并检查amplify.js lib下发生了什么,则得到以下信息:
//this is what has been saved when I created a subscription
subscriptions[ topic ][ i ].callback
(L){return i.subscribeFn(L);}
.
//this is what was passed as a callback for the unsubscribe function
callback
(S){return i.subscribeFn(S);}
逻辑上没有区别,但是参数不同,因此我无法退订。
最佳答案
WebSharper 3无法将对模块函数的调用优化为函数值(在引号中表示为lambda),因此它成为每个调用站点上的新函数。
一种解决方案是将模块功能捕获为局部功能值:
let subscribeFn = fun (o: obj) -> subscribeFn o
(WebSharper 4 beta已经进行了此优化。)