在 buckle 脚本中定义一个闭包变量
Define a closure variable in buckle script
我正在尝试将以下 ES6 脚本转换为 bucklescript,但我终生无法弄清楚如何在 bucklescript
中创建 "closure"
import {Socket, Presence} from "phoenix"
let socket = new Socket("/socket", {
params: {user_id: window.location.search.split("=")[1]}
})
let channel = socket.channel("room:lobby", {})
let presence = new Presence(channel)
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
socket.connect()
presence.onSync(() => renderOnlineUsers(presence))
channel.join()
我无法具体弄清楚的部分是 let response = ""
(或者在这种情况下是 var,因为 bucklescript 总是使用 var
s):
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
到目前为止我得到的最接近的不包括 result
声明
...
...
let onPresenceSync ev =
let result = "" in
let listFunc = [%raw begin
{|
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
|}
end
] in
let _ =
presence |. listPresence (listFunc) in
[%raw {| console.log(result) |} ]
...
...
编译为:
function onPresenceSync(ev) {
var listFunc = (
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
);
presence.list(listFunc);
return ( console.log(result) );
}
result
作为优化被删除,因为它被认为未使用。使用依赖于 BuckleScript 生成的代码的 raw
代码通常不是一个好主意,因为在生成的代码中您可能会遇到很多意外。
改变编译器认为不可变的变量也不是一个好主意,因为它会基于值永远不会改变的假设来执行优化。
此处最简单的修复方法是将 [%raw {| console.log(result) |} ]
替换为 Js.log result
,但看看 listFunc
如何用 OCaml 编写可能会有所启发:
let onPresenceSync ev =
let result = ref "" in
let listFunc = fun [@bs] id item ->
let count = Js.Array.length item##meta in
result := {j|$id (count: $count)\n|j}
in
let _ = presence |. (listPresence listFunc) in
Js.log !result
请注意,result
现在是一个 ref
单元格,这是您在 OCaml 中指定可变变量的方式。 ref
单元格使用 :=
更新,它包含的值使用 !
检索。另请注意 [@bs]
注释,用于指定传递给外部高阶函数的函数所需的 an uncurried function。以及使用的字符串插值语法:{j| ... |j}
我正在尝试将以下 ES6 脚本转换为 bucklescript,但我终生无法弄清楚如何在 bucklescript
中创建 "closure" import {Socket, Presence} from "phoenix"
let socket = new Socket("/socket", {
params: {user_id: window.location.search.split("=")[1]}
})
let channel = socket.channel("room:lobby", {})
let presence = new Presence(channel)
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
socket.connect()
presence.onSync(() => renderOnlineUsers(presence))
channel.join()
我无法具体弄清楚的部分是 let response = ""
(或者在这种情况下是 var,因为 bucklescript 总是使用 var
s):
function renderOnlineUsers(presence) {
let response = ""
presence.list((id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
response += `<br>${id} (count: ${count})</br>`
})
document.querySelector("main[role=main]").innerHTML = response
}
到目前为止我得到的最接近的不包括 result
声明
...
...
let onPresenceSync ev =
let result = "" in
let listFunc = [%raw begin
{|
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
|}
end
] in
let _ =
presence |. listPresence (listFunc) in
[%raw {| console.log(result) |} ]
...
...
编译为:
function onPresenceSync(ev) {
var listFunc = (
(id, {metas: [first, ...rest]}) => {
let count = rest.length + 1
result += `${id} (count: ${count})\n`
}
);
presence.list(listFunc);
return ( console.log(result) );
}
result
作为优化被删除,因为它被认为未使用。使用依赖于 BuckleScript 生成的代码的 raw
代码通常不是一个好主意,因为在生成的代码中您可能会遇到很多意外。
改变编译器认为不可变的变量也不是一个好主意,因为它会基于值永远不会改变的假设来执行优化。
此处最简单的修复方法是将 [%raw {| console.log(result) |} ]
替换为 Js.log result
,但看看 listFunc
如何用 OCaml 编写可能会有所启发:
let onPresenceSync ev =
let result = ref "" in
let listFunc = fun [@bs] id item ->
let count = Js.Array.length item##meta in
result := {j|$id (count: $count)\n|j}
in
let _ = presence |. (listPresence listFunc) in
Js.log !result
请注意,result
现在是一个 ref
单元格,这是您在 OCaml 中指定可变变量的方式。 ref
单元格使用 :=
更新,它包含的值使用 !
检索。另请注意 [@bs]
注释,用于指定传递给外部高阶函数的函数所需的 an uncurried function。以及使用的字符串插值语法:{j| ... |j}