- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我刚刚开始在 node-js 端使用 clojurescript。我用它来构建将在节点上运行的命令行工具。现在我已经设置了我的概念验证并且或多或少地做了我想做的事情,是时候更好地组织代码了。
在 JS 上,当我需要类似于已配置的 http 客户端的东西时,我通常会导出一个函数,该函数接受基本参数并返回一个对象,该对象具有绑定(bind)到该参数的方法(通常使用显示模块模式)。类似于在 OOP 上创建新实例的东西。这是我如何在 JS 上执行此操作的一个小示例:
const request = require('request')
module.exports = (user, pass, baseUrl) => {
const client = request.defaults({baseUrl, auth: {user, pass}})
const getSomething = (name) => client.get('resources/' + name)
const createSomething = (name, options) => client.post('resources', {...})
return { getSomething, createSomething }
}
但是在 clojurescript 上我找不到合适的方法。所有定义都是在编译时计算的顶级声明,并且制作上述结构需要使用客户端参数声明我的所有函数,然后部分应用它们并在逻辑主体上使用它们。这可能是这样的:
(ns some-client [:require ["request" :as request]])
(defn get-something [client, name]
(.get client (str "resources/" name)))
(defn create-something [client, name, options]
(.post client (str "resources") {:name name :data: options}))
(defn make-client [usr, pass, baseUrl]
(let [client (.defaults request {:auth {:user usr :pass pass} :baseUrl baseUrl})]
{:get-something (partial get-something client)
:create-something (partial create-something client)}))
这可能看起来还不错,但是一旦您需要在另一个所有功能都需要此类客户端的地方使用它,事情就会开始变得困惑。您将需要在所有功能上接受客户端,如果其他命名空间只是您需要在另一个地方使用的功能集合,您将被迫遵循返回客户端创建者的相同模式,接受客户端您依赖并确保将其传递给可能需要它的每个功能。我可以变得像这样可怕:
(ns other-helper)
(defn trivial-stuff [client name bla]
(let [get-something (client :get-something)]
(get-something name))) ; make things like filtering and that
(defn more-trivial-stuff [client name bla]
(let [get-something (client :get-something)])
(get-something name)) ; make things like filtering and that
(defn non-trivial-stuff [client name bla]
(->>
(trivial-stuff client name bla)
(more-trivial-stuff client name)))
(defn more-non-trivial-stuff [client name bla]
(->>
(trivial-stuff client name bla)
(more-trivial-stuff client name)))
(defn compile-utils [client]
{:more-non-trivial (partial more-non-trivial-stuff client)
:non-trivial (partial non-trivial-stuff client)})
我无法为客户端制作任何 def
,因为我将在运行时需要凭据,所以我必须接受所有这些东西作为参数并绑定(bind)结果,对我来说这看起来像大量样板代码和重复代码根本无法维护。
clojurians 有更好的方法吗?在这方面有任何风格指南吗?这是我第二次接触 clojurescript,起初它看起来非常吸引人,但一旦你开始构建重要的东西,它就会开始变得困惑。
注意:为了简单起见,我没有管理任何 js 互操作或使用 channel 进行异步处理。我只是将 js 对象声明为普通的 cljs 映射并将所有内容都视为同步的,但是包括 js 互操作和所有这些东西会使事情变得更糟。
编辑(澄清):
我的问题不是这在 clojure 上是否可行,我知道这是可能的,因为 CLJS 和 JS 共享所需的功能集以使其成为可能。然而,在完全不同的语言上使用相同的模式不仅感觉不对,而且由于 lisp 语法,它看起来也很难看。我能想到的其他替代方案看起来也很丑陋,并且涉及大量重复,因为它需要让客户使用它并在每个函数上传递它,这会导致非常重复和分散注意力的代码。
为了弄清楚我将如何在 js 上使用它,它会像这样
const makeClient = require('./my-http')
const client = makeClient('my-user','my-pass','http://google.es')
client.getSomething('dude')
如您所见,我可以根据需要创建具有不同设置的客户端,我什至可以进行一些解构并仅选择我需要的方法,因为它们根本不依赖于它们的绑定(bind)。
最佳答案
注意:我还没有“愤怒地”使用过 Clojure/Script,所以这对我来说也是一种学习经历 :) 不幸的是,我还没有在 REPL 中验证代码。
如果我没理解错的话,JS模块模式就是一个函数,返回两个函数的字典。在你的代码中的某个时刻,你“创建”了这个模块,也许给它一个名字,然后你在你的代码中传递它,就像这样:
let client = require("mymodule")("user", "pass", "http://example.com");
client.getSomething("foo")
您可以使用 ClojureScript 做同样的事情:
(defn create-client [user pass base]
(let [get-something (fn [name] ...)
create-something (fn [name other] ...)]
{:get get-something :create create-something}))
(let [client (create-client "user" "pass" "http://example.com")]
((client :get) "foo"))
现在可以说这可能看起来有点笨拙,但它是完全相同的代码:关闭几个变量,将两个函数粘贴在一个映射中,从映射中获取一个函数并调用它。
你的问题的第二部分看起来是关于全局状态的——你必须随身携带 client
对象,而且感觉很笨重。我不认为它在 Javascript 中看起来更好?
let client = require("mymodule")("user", "pass", "http://example.com");
let trivialStuff = (client, name, blah) => { client.getSomething(name); ... };
let moreTrivialStuff = (client, name, blah) => { client.getSomething(name); ... };
let nonTrivialStuff = (client, name, blah) => {
let result = trivialStuff(client, name, blah)
return moreTrivialStuff(client, name, result)
}
即您仍在传递 client
。您可以在初始化后使其成为模块级变量,但随后您将失去在运行时创建两个不同客户端的能力。
您是说使用揭示模块模式还会公开 nonTrivialStuff
,因此您可以执行 client.nonTrivialStuff()
?
如何创建一个 namespace ,其中包含所有需要client
的函数(它可能只是一个包含 JS requests
客户端的普通映射),并直接使用它们?
例如
(ns some-client [:require ["request" :as request]])
(defn make-client [usr pass base-url]
{:client (.defaults request {:auth {:user usr :pass pass} :baseUrl baseUrl})}) ;; you might want to use #js here, since you usually cannot pass CLJS maps to JS directly
(defn get-something [client name]
(.get (client :client) (str "resources/" name)))
(defn create-something [client name options]
(.post (client :client) (str "resources") {:name name :data options}))
然后在其他命名空间中:
(ns other-code [:require [some-client :as client]])
(def c (atom nil))
;; get user and pass from runtime, then call
(reset! c (client/make-client user pass base-url))
;; use like so
(client/get-something @c "name")
我选择将 JS 客户端对象放入 CLJS 映射中以实现灵 active ——将来您可能希望将更多数据添加到该映射中。当然,客户端代码不会更改,因为它应该将其视为不透明值。
关于javascript - clojurescript 相当于 javascript 的模块模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49611955/
在 Chapel 中以固定增量遍历一系列实数的最惯用方法是什么? C 等效代码为: for (x = 0.0; x start, "Stop must be greater than start");
在编写我的 VBA 宏时,我经常使用“GoTo”以便在不离开 Sub 的情况下跳转到宏的前一部分。现在我正在将我所有的宏转换为 Google Apps 脚本,我正试图找到“GoTo”的等效项。 Sub
作为一个(不幸)对 jQuery 的了解多于 raw javascript 的人,我现在正在学习是时候用原始 javascript 替换我的所有代码了。不,这不是必需的,但对我来说这是一种更简单的学习
当我运行 git help -a它向我显示了内部命令列表、我所有的别名和我所有的外部 git 命令(即我的路径中以 git- 开头的任何可执行文件)。我想要的是一个可以作为 git which 运行的
我正在使用的查询: SELECT COUNT(*), SUM(amount) AS amount, FROM_UNIXTIME(added, '%W (%e/%m)') AS dail
我有一堆我正在调试的脚本,都是嵌套的并且非常讨厌。 只是想知道我是否能够设置一些与 bash 的 -x 选项等效的环境变量。这将为我节省大量时间。 我已经寻找答案,但似乎它不存在 - 希望你们聪明的人
ObjC [MyObject doThisWithString:string?: [MyObject otherString]]; 我如何在 Swift 中执行此操作? extension MyObj
我目前正在运行 Sonar 来对我的代码进行静态分析。当我在分析java文件并想抑制某个警告时,我使用了@SuppressWarnings(nameOfTheWarningOnSonar)注解。我想知
我最近一直在研究 Elixir 和 Akka,这让我想到:Clojure 中的等价物是什么? 我发现了几篇关于代理与 Actor 的“消息吞吐量比较”帖子,但它们来自 8 年前 一个答案曾经是agen
我以前工作的地方,我们使用 Mercurial 进行版本控制。我有一份新工作,我们在那里使用 Subversion。我是 Subversion 的新手。 我发现自己想知道自从我在远程仓库上结帐以来 c
寻找一种等效的剪切和粘贴策略来复制 vim 的“cut til”。如果我真的知道它在 vim 中的名称,我敢肯定这是 googleable,但这是我要找的: 如果我有一个像这样的文本块: foo ba
我有一段 .NET 代码,我想将其移植到 64 位。这些代码基本上是一组对其他 C dll 的 P/Invoke 调用。 C dll 中的函数之一具有参数“size_t”。我应该在我的 P/Invok
开发 iPhone 应用程序的标准开发者平台是什么,例如相当于 Eclipse? 最佳答案 Xcode 是 iOS 开发的标准且唯一(由 Apple 支持)IDE。它也是必需的,因为如果您想要任何开发
我想将某些内容推送到 iPhone 的响应者链上。也就是说,我想将选择器发送到 UIResponder子类,如果它不响应所述选择器,则将其传递给其 nextResponder . 有什么想法吗? 最佳
我需要一个与 SQL 中的此查询等效的 Firebase 查询: select * from your_table where id in (123, 345, 679) 你会如何在 firebase
我有一个很好的解决方案: $.get('getdbstuff.php?type=meta,'.$var_id, function(data){ $(data).appendTo("head")
我正处于 Cassandra 应用程序数据建模的初始阶段。此应用程序具有现有的关系持久层,必须用 Cassandra 替换。 应用程序为用户使用一个名为login_log 的表,它提供所有应用程序中任
如标题所述,TensorFlow 是否存在与 numpy.all() 函数等效的函数来检查 bool 张量中的所有值是否为 True?实现此类检查的最佳方法是什么? 最佳答案 使用tf.reduce_
在 Stata 中,如果我有以下变量:var1、var2、var3、var4、var5 和 var6,我可以使用命令 var* 选择所有它们。 R 有类似的功能吗? 最佳答案 “dplyr”包中的se
我正处于 Cassandra 应用程序数据建模的初始阶段。此应用程序具有现有的关系持久层,必须用 Cassandra 替换。 应用程序为用户使用一个名为login_log 的表,它提供所有应用程序中任
我是一名优秀的程序员,十分优秀!