gpt4 book ai didi

javascript - FFI 中带有 Aff 回调的函数

转载 作者:行者123 更新时间:2023-12-02 02:56:05 27 4
gpt4 key购买 nike

我正在尝试包装一个 Javascript 库,其中有一个方法 A.bar(f) ,该方法将函数 f : B -> void 作为参数。

由于我想使用 bar 执行一些异步计算,因此在 Purescript 端,我有一个函数声明

foreign import foo :: Fn2 A (B -> Aff Unit) -> EffectFnAff Unit

在其相应的 Javascript 文件中,我有类似的内容

exports.foo = function (a, f) {
return function (onError, onSuccess) {
a.bar(function (b) {
f(b)
})

return function (cancelError, cancelerError, cancelerSuccess) {
cancelerSuccess()
}
}
}

我遇到的问题是 f(b) 是一个 Aff 对象,我不知道如何在 Javascript 端执行它。

最佳答案

从 FFI-ied JavaScript 访问 PureScript 数据结构始终是一个坏主意。您不仅依赖于库的特定编写方式(没有编译器支持来捕获错误!),而且还依赖于编译器本身,因为运行时表示可能会从一个编译器版本更改为另一个编译器版本(请注意,这并不适用于 EffectFnAff,因为它明确适用于 FFI,并仔细定义为 in terms of EffectFn2 )。

在 FFI 中表示有效计算的方法是通过 Effect:

foreign import foo :: Fn2 A (B -> Effect Unit) -> EffectFnAff Unit

现在可以按照您的方式从 JavaScript 调用此类函数 - 例如 f(b)

如果您希望库的使用者提供 Aff,您要做的就是制作一个包装器:

foreign import foo_ :: Fn2 A (B -> Effect Unit) (EffectFnAff Unit)

foo :: A -> (B -> Aff Unit) -> Aff Unit
foo a f = fromEffectFnAff $ runFn2 foo_ a (launchAff_ <<< f)

然后您只需导出包装器 foo,而不是 FFI 导入 foo_


在某种程度上相关的说明中,我还建议取消 EffectFnAff,因为您实际上并没有启动任何异步内容,而是始终调用 cancelerSuccess()

所以,我会推荐这个:

// JavaScript
exports.foo = (a, f) => a.bar(f)

-- PureScript
foreign import foo_ :: EffectFn2 A (B -> Effect Unit) Unit

foo :: A -> (B -> Aff Unit) -> Aff Unit
foo a f = liftEffect $ runEffectFn2 foo_ a (launchAff_ <<< f)

包装器在两个地方仍然有 Aff - 这是假设您出于自己的原因需要将整个内容放入 Aff 中。否则它可能只是 foo = runEffectFn2 foo_

关于javascript - FFI 中带有 Aff 回调的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61103206/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com