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 中的伪代码:
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)
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)