ClojureScript 中的流畅界面

nha*_*nha 1 clojure clojurescript

我正在 ClojureScript 中创建一个库,它将公开一个公共 JavaScript API。由于它必须模仿现有 JavaScript 库的 API,因此我想提供相同类型的流畅 API:

myLib.prepareToDo()
     .something()
     .and('also')
     .somethingElse()
     .run(function(err, result) {
         console.log("yay!");
});
Run Code Online (Sandbox Code Playgroud)

在 Javascript 中,我们可以创建一个流畅的 API,就像这个站点点):

var MyClass = function(a) {
    this.a = a;
}

MyClass.prototype.foo = function(b) {
    // Do some complex work   
    this.a += Math.cos(b);
    return this;
}
Run Code Online (Sandbox Code Playgroud)

然后我可以这样称呼它:

var obj = new MyClass(5);
obj.foo(1).foo(2).foo(3);
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,thisClojureScript 中没有 的概念,尽管显然可以访问它this-as

我不知道如何使用它,因此我的问题。

如何在 ClojureScript 中创建流畅的界面?

ez1*_*1sl 5

(defrecord)这是拯救的答案。将“神奇”协议扩展Object到我们的记录或类型会导致定义的方法在 JavaScript 对象中显示为成员函数。为了启用“流畅的界面”,某些方法返回MyClass.

(defrecord MyClass [a b]
    Object
      (something [this] this)
      (and-then [this s] (assoc this :a s))
      (something-else [this] (assoc this :b (str a "-" a)))
      (run [this f] (f a b)))
Run Code Online (Sandbox Code Playgroud)

然后我们就可以拥有一个 JavaScript 客户端,如下所示:

var myClass = new my_namespace.core.MyClass();
myClass.something()
   .and_then("bar")
   .something_else()
   .run(function(a, b) { 
       console.log(a + " - " + b) });
Run Code Online (Sandbox Code Playgroud)