在函数式编程中处理线程资源(如连接)的方法

Mat*_*zer 5 javascript resources functional-programming

假设您需要连接到数据库。

因此,您将 aDbConnection作为具有以下类型的某个假设函数的最后一个参数:doDbStuff :: Int -> DbConnection -> Int

也许还有其他函数也依赖于 a DbConnection,并且所有这些函数都在执行写操作。因此,这些可以单独运行或作为原子操作(即事务)的一部分运行。

由于人们可能想要DbConnection使用pool进行管理,并且函数可能是也可能不是原子操作的一部分,因此它们没有实现代码来DbConnection从池中获取和释放实例。

现在,这些函数是一个长函数组合的一部分,其中某些决定可能涉及不需要DbConnection. 也就是说,aDbConnection可能会从池中取出并被另一个请求使用,这可能会产生瓶颈。

还有一种替代方案,其中不会注入DbConnection一个高阶函数,例如withConnection :: (DbConnection -> a) -> a,因此每个函数都可以使用DbConnection,使用它,并且整个withConnection过程负责获取和释放连接。这里的缺点是,将许多功能作为原子操作的一部分进行协作变得更加困难。

所以...

目前,我一直在使用#2 方法。顺便说一句,有没有其他选择可以保留两种方法中的优点?

JavaScript 中的伪代码:

方法#1

const connectionString = '[whatever]'
const env = { connection: acquire (connectionString) }

const output = composition (arg0) (argN) (env)
// then, release the connection

// f :: a -> b -> { connection: DbConnection }
const f = x => y => ({ connection }) => 
    doDbStuff (x + y) (connection)
Run Code Online (Sandbox Code Playgroud)

方法#2

const withConnection = f => [stuff to acquire the connection, and aftewards, release it]
const env = { withConnection }

const output = composition (arg0) (argN) (env)

// type FnConnection DbConnection c = c -> a
// f :: a -> a -> { connection: FnConnection }
const f = x => y => ({ withConnection }) => 
    withConnection (doDbStuff (x + y))
Run Code Online (Sandbox Code Playgroud)