在Clojurescript中是否有办法创建一个异步函数或将一个函数包入一个Promise中的宏来模拟它? 我目前的使用情况是用它的异步版本来替换下面的函数,它需要一个回调--顺便说一句,这是为了一个 AWS lambda函数.
// Old style
function(args, callback) {
// Use callback(e) for errors
// Use callback(null, value) for the result
}
// New style
async function(args) {
return value; // success path
throw new Error(); // error path
}
鉴于这是Clojurescript,使用 await
不是问题。而我知道,这可以简单地返回一个承诺,遵守的。async
要求.所以它解析到一些糖代码来创建Promise,为我捕捉所有错误,并在快乐的路径上调用resolve,否则拒绝。
浏览 clojure.core.async
和文件--包括 clojurescript参考文献我没有找到任何东西。
Node 8和更新的版本都有 承诺 做你想要的事情。
遵循常见的错误优先回调风格的函数,即使用(err, value) => ... 回调作为最后一个参数,并返回一个返回承诺的版本。
编辑: 我花了一点时间写了一个宏,它可以 promisify
我对这个结果很满意。请注意,这个宏需要保存在CLJC文件中。
;; macros.cljc ;;;;;;;;;;
(ns server.macros)
(defmacro promisify [method obj params]
`(js/Promise.
(fn [resolve# reject#]
(~method ~obj ~params
(fn [err# result#]
(if err#
(reject# err#)
(resolve# result#)))))))
;; main.cljs ;;;;;;;;;;
(ns server.main
(:require-macros [server.macros :refer [promisify]])
(:require ["aws-sdk" :as aws]))
(defn main! []
(println "App loaded...")
(let [creds (aws/SharedIniFileCredentials. #js {:profile "example-profile"})
_ (set! (.-credentials aws/config) creds)
s3 (aws/S3.)]
(-> (promisify .listBuckets s3 #js {})
(.then #(println "DATA:" %))
(.catch #(println "ERROR:" %)))))
而且输出结果和之前一样
$ node target/main.js
App loaded...
DATA: #js {:Buckets #js [#js {:Name demo-test-bucket, :CreationDate #inst "2019-05-05T17:32:17.000-00:00"} #js {:Name subdomain.mydomain.com, :CreationDate #inst "2019-06-19T04:16:10.000-00:00"}], :Owner #js {:DisplayName username, :ID 9f7947b2d509e2338357d93e74f2f88a7528319ab3609b8d3b5be6b3a872dd2c}}
这个宏基本上是一个Clojure版本的... 此代码.
编辑2: 还有 本馆 如果你真的想使用core.async,那可能会很有趣。