2016-09-02 6 views
5

पर node.js एपीआई का बेवकूफ रूपांतरण मैं एक इलेक्ट्रॉन अनुप्रयोग लिख रहा हूं, और इस एप्लिकेशन में मुझे कुछ नोड.जेएस एपीआई के साथ बातचीत करने की आवश्यकता है - फाइलें पढ़ें, निर्देशिका प्रविष्टियां प्राप्त करें, घटनाओं को सुनें।क्लोजरस्क्रिप्ट

बेशक, मैं क्लोजरस्क्रिप्ट लिख सकता हूं, वैसे ही मैं जावास्क्रिप्ट लिखूंगा, लेकिन मैं जानना चाहता हूं कि क्लोजरैंक कॉलबैक-स्टाइल एपीआई, स्ट्रीम, इवेंटइमीटर पर क्या लेता है और मैं कैसे नोड.जेएस एपीआई के आसपास रैपर लिखता हूं जो ClojureScript में विदेशी नहीं दिखता है।

विशिष्ट होना करने के लिए:

  1. कैसे एक एपीआई कि लपेटता कॉलबैक शैली Node.js एपीआई लिख सकता हूँ। (कहें, fs.readdir)
  2. मैं EventEmitter- जैसी एपीआई के साथ कैसे बातचीत करूं?
  3. (शायद पी 2 के करीब) मैं node.js स्ट्रीम एपीआई के साथ कैसे काम करूं?

उत्तर

6

मेरे अनुभव में, इन मुद्दों को संभालने का सबसे आसान तरीका core.async का उपयोग करना है।

कॉलबैक शैली

उदाहरण के लिए

, एक निर्देशिका पढ़ने:

(def fs (js/require "fs")) 

(defn read-dir [path] 
    (let [out (async/chan)] 
    (.readdir fs path 
     (fn [err files] 
     (async/put! (if err err files)) 
     (async/close! out))) 
    out)) 

मैं एक चैनल में परिणाम गुजरती हैं, भले ही उस परिणाम एक त्रुटि है। इस तरह, कॉलर त्रुटि करके त्रुटि को संभाल सकता है। उदा .:

(let [res (<! (read-dir "."))] 
    (if (instance? js/Error res) 
    (throw res) 
    (do-something res)) 

अपने ही परियोजनाओं में मैं cljs-asynchronize उपयोग करते हैं, आप core.async संगत कार्यों के लिए में NodeJS कॉलबैक शैली कार्यों कन्वर्ट करने के लिए अनुमति देता है। उदाहरण के लिए, इस पहले उदाहरण के रूप में ही है:

(defn read-dir [path] 
    (asynchronize 
    (.readdir fs path ...))) 

अन्त में, चैनलों के माध्यम से त्रुटियों से निपटने का एक अच्छा तरीका है के लिए, मैं व्यक्तिगत रूप "Error Handling with Clojure Async" काफी उपयोगी पाया।

(try 
    (let [res (<? (read-dir "."))] 
    (do-something res)) 
    (catch js/Error e 
    (handle-error e)) 

स्ट्रीम

स्ट्रीम एपीआई और भी आसान कर रहे हैं:: तो, आप की तरह उपरोक्त त्रुटि हैंडलिंग कोड लिख सकते हैं

(defn create-read-stream [path] 
    (let [out (async/chan) 
     stream (.createReadStream fs path)] 
    (.on stream "close" #(async/close! out)) 
    (.on stream "data" #(async/put! out %)) 
    out)) 
+1

क्या पहले स्निपेट के साथ उदाहरणों को बदलने/पकड़ने के बिना परिवर्तन किए गए हैं? –

+1

हां। असल में,

1

मुझे लगता है कि आपके सवाल का जवाब है, "यह निर्भर करता है । "।

हमेशा सभी विकल्पों पर विचार करें। सिर्फ इसलिए कि core.async एक सेटिंग में समझ में आता है यह हर जगह सबसे अच्छा विकल्प नहीं बनाता है।

सामान्य कॉलबैक का उपयोग करना ठीक है अगर इसे केवल एक बार बुलाया जाता है और किसी अन्य चीज़ के साथ समन्वय की आवश्यकता नहीं होती है (उदाहरण के लिए fs.readdir)।

core.async उन चीज़ों की तरह स्ट्रीम के लिए बहुत अच्छा है जहां आपको अंतिम परिणाम (जैसे "data","data","data","close","end") में जमा करना चाहते हैं।

वादे एक और विकल्प भी हैं।

अधिक समन्वय आपको अधिक समझने की आवश्यकता है core.async बनाता है। यदि आपको विकल्पों पर विचार करने की आवश्यकता नहीं है।

संबंधित मुद्दे