Как создать асин c функцию в Clojurescript? - PullRequest
0 голосов
/ 02 мая 2020

Есть ли способ в Clojurescript создать функцию asyn c или макрос, чтобы обернуть функцию в Promise для ее моделирования? Мой текущий вариант использования заключается в замене следующей функции, которая принимает обратный вызов, на ее асин c версию - кстати, это для AWS лямбда-функции .

// 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. Таким образом, он разрешает некоторый сахарный код для создания Обещания, перехвата всех ошибок для меня и вызова решения на счастливом пути или отклонения в противном случае.

Просмотр по clojure.core.async и документам, включая clojurescript reference , я ничего не нашел.

1 Ответ

1 голос
/ 04 мая 2020

Узел 8 и новее поставляются с util.promisify , который делает то, что вы хотите:

Принимает функцию в соответствии с общим стилем обратного вызова с ошибкой, т. Е. Принимает (err , value) => ... обратный вызов в качестве последнего аргумента и возвращает версию, которая возвращает обещания.

EDIT : я потратил немного времени на написание макроса, который делает promisify и я доволен результатом. Обратите внимание, что макрос должен быть сохранен в файле CLJ C:

;; 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.asyn c тоже.

...