गो

2016-03-10 13 views
5

में चैनलों के साथ वादा को कार्यान्वित करना मैं जासूस में वादा को लागू करने की कोशिश कर रहा हूं जो जावास्क्रिप्ट में समान होगा।गो

  1. एक goroutine है, जो सही दूर मुख्य goroutine को Promise लौट चलाएँ:

    type Promise struct { 
         Result chan string 
         Error chan error 
    } 
    
    func NewPromise() (*Promise) { 
         r := make(chan string, 1) 
         e := make(chan error, 1) 
         return &Promise{ 
           Result: r, 
           Error: e, 
         } 
    } 
    
    func main() { 
         var p = NewPromise() 
    
         go func(p *Promise) { 
           time.Sleep(time.Duration(5)*time.Second) 
           p.Result <- "done" 
         }(p) 
    
         if <- p.Result { 
           fmt.Println(<-p.Result) 
         } 
    
         // Is it possible to do something else here while wait for 5s? 
    
         // Once Promise is fulfilled after 5s, the Result is available. 
    } 
    

    मैं निम्नलिखित कैसे करते हैं। जबकि, कुछ भी के लिए प्रतीक्षा या तो Promise.Result या Promise.Error

  2. एक बार कुछ भेज दिया जाता है के लिए भेजा जाना goroutine से लौट सकते हैं और है कि उपलब्ध चैनल पढ़ने के लिए बनाने के

  3. एसिंक्रोनस रूप से मुख्य दिनचर्या पर कुछ करना।

उत्तर

7

चैनलों का उपयोग किए बिना एक अलग दृष्टिकोण है, जो यह एक छोटा सा तेजी से बनाता है/और अधिक कुशल:

type Promise struct { 
    wg sync.WaitGroup 
    res string 
    err error 
} 

func NewPromise(f func() (string, error)) *Promise { 
    p := &Promise{} 
    p.wg.Add(1) 
    go func() { 
     p.res, p.err = f() 
     p.wg.Done() 
    }() 
    return p 
} 

func (p *Promise) Then(r func(string), e func(error)) { 
    go func() { 
     p.wg.Wait() 
     if p.err != nil { 
      e(p.err) 
      return 
     } 
     r(p.res) 
    }() 
} 

playground

1

तरीके यह करने के लिए एक टन कर रहे हैं, लेकिन क्या मैं उदाहरण के लिए किया है NewPromise निकाला जाता है() एक आर्ग कि परिणाम और त्रुटि चैनलों को स्वीकार करेंगे के रूप में एक समारोह लेने के लिए। फिर न्यूप्रोमाइज़ विधि इस फ़ंक्शन के साथ एक जाने-माने दिनचर्या शुरू करती है, जिससे उन चैनलों के साथ वादा वापस किया जा सकता है। अगर आप कॉल करते हैं। फिर विधि, यह मूल रूप से दो कार्यों को तर्क के रूप में लेता है। एक ऐसा परिणाम जो आप परिणाम चैनल (स्ट्रिंग) के माध्यम से गुज़र रहे हैं और एक त्रुटि चैनल (त्रुटि) के परिणाम प्रकार को संभालता है। तब। विधि फिर एक goroutine में एक निजी .then() विधि को कॉल करने के लिए पहले, या तो परिणाम, या त्रुटि का चयन करने के लिए कॉल करता है, फिर प्रत्येक परिणाम के लिए उपयुक्त फ़ंक्शन को कॉल करता है।

उदाहरण के लिए, मैंने केवल एक साधारण टिकर का उपयोग किया है जो एक सेकंड प्रतीक्षा करता है और फिर परिणाम चैनल के माध्यम से "हाय" भेजता है।

मुझे आशा है कि यह आपको ऐसा करने का एक तरीका बताएगा।

GoLang खेल का मैदान: https://play.golang.org/p/xc1xvv7hRx

2

Martin Sulzmann द्वारा एक कागज "From Events to Futures and Promises and back" कहा जाता है (फरवरी 2016 में प्रकाशित) जिसमें आप जो हासिल करने की कोशिश कर रहे हैं उसे शामिल करते हैं। सार कहता है:

चैनल संचार और वायदा/वादे के आधार पर घटनाक्रम शक्तिशाली हैं लेकिन समवर्ती प्रोग्रामिंग के लिए प्रतीत होता है कि विभिन्न अवधारणाएं हैं। हम दिखाते हैं कि एक अवधारणा को आश्चर्यजनक रूप से कम प्रयास के साथ दूसरे के संदर्भ में व्यक्त किया जा सकता है। हमारे परिणाम घटनाओं और वायदा/वादे को लागू करने के लिए हल्के वजन पुस्तकालय आधारित दृष्टिकोण प्रदान करते हैं। अनुभवजन्य परिणाम दिखाते हैं कि हमारा दृष्टिकोण अभ्यास में अच्छी तरह से काम करता है।

कागज के अनुसार, वायदा इस तरह दिखेगा:

type Comp struct { 
    value interface{} 
    ok bool 
} 

type Future chan Comp 

func future(f func() (interface{}, bool)) Future { 
    future := make(chan Comp) 

    go func() { 
     v, o := f() 
     c := Comp{v, o} 
     for { 
      future <- c 
     } 
    }() 

    return future 
} 

जबकि वादों इस प्रकार लागू किया जाता है:

type Promise struct { 
    lock chan int 
    ft Future 
    full bool 
} 

func promise() Promise { 
    return Promise{make(chan int, 1), make(chan Comp), false} 
} 

func (pr Promise) future() Future { 
    return pr.ft 
} 

विवरण, combinators और अधिक के लिए कागज पढ़ें।

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