2016-05-09 10 views
8

मैं कोड में विधि चेनिंग को लागू करना चाहता हूं, Alamofire विधियों की संभावना है। उदाहरण के लिए, की तरह नीचेस्विफ्ट - विधि

getListForID(12).Success { 
    // Success block 
}. Failure { 
    // Failure block 
} 

मैं कैसे समारोह getListForID बन जाएगा मेरी समारोह का उपयोग करने के अगर मैं है?

+0

आप एक वस्तु भी 'success' और' failure' संपत्ति और 'success' सेटर है कि लौट सकते हैं देता है कि, btw आप वादेकिट का उपयोग कर सकते हैं जो यह करता है http://promisekit.org/ –

+0

आप मेरे आलेख को आजमा सकते हैं जो यह करता है: [स्विफ्ट में चेनिंग असिंक्रोनस फ़ंक्शंस] (https://medium.com/@jhoomuck/composing-asynchronous-functions- इन-स्विफ्ट-एसीडी 24 सीएफ 5 बी 4 9 4) – zeitgeist7

उत्तर

7

महान अंक @dasblinkenlight और @Sulthan पर विस्तार करने के लिए - यहां एक सुविधाजनक उदाहरण है कि आप अपने इच्छित फ़ंक्शन को सफलतापूर्वक और विफलता बंद करने के लिए कैसे प्राप्त कर सकते हैं, सुविधाजनक वाक्यविन्यास में।

सबसे पहले, आपको 'परिणाम हैंडलर' का प्रतिनिधित्व करने के लिए एक नई कक्षा को परिभाषित करना होगा। यह है कि आपका success और failure फ़ंक्शंस पास हो जाएंगे, जिससे आप अपना पूरा करने वाले ब्लॉक तर्क को बनाने के लिए कई पिछला बंद करने की अनुमति दे सकते हैं। आप इसे कुछ इस तरह दिखाई चाहता हूँ:

class ResultHandler { 

    typealias SuccessClosure = RequestHandler.Output->Void 
    typealias FailureClosure = Void->Void 

    // the success and failure callback arrays 
    private var _successes = [SuccessClosure]() 
    private var _failures = [FailureClosure]() 

    /// Invoke all the stored callbacks with a given callback result 
    func invokeCallbacks(result:RequestHandler.Result) { 

     switch result { 
      case .Success(let output): _successes.forEach{$0(output)} 
      case .Failure: _failures.forEach{$0()} 
     } 
    } 

    // remove all callbacks – could call this from within invokeCallbacks 
    // depending on the re-usability of the class 
    func removeAllCallbacks() { 
     _successes.removeAll() 
     _failures.removeAll() 
    } 

    /// appends a new success callback to the result handler's successes array 
    func success(closure:SuccessClosure) -> Self { 
     _successes.append(closure) 
     return self 
    } 

    /// appends a new failure callback to the result handler's failures array 
    func failure(closure:FailureClosure) -> Self { 
     _failures.append(closure) 
     return self 
    } 
} 

यह आपको परिभाषित करने के लिए एक से अधिक सफलता या विफलता बंद पूरा होने पर निष्पादित करने की अनुमति देगा। यदि आपको वास्तव में एकाधिक बंद करने की क्षमता की आवश्यकता नहीं है, तो आप सरणी को अलग करके कक्षा को सरल बना सकते हैं - और केवल अंतिम अतिरिक्त सफलता और विफलता समापन ब्लॉक को ट्रैक रखने के बजाय।

अब तुम सब करने की है एक समारोह है कि एक नए ResultHandler उदाहरण उत्पन्न करता है और उसके बाद करता है एक दिया अतुल्यकालिक अनुरोध को परिभाषित है, invokeCallbacks विधि पूरा होने पर लागू किया जा रहा है:

func doRequest(input:Input) -> ResultHandler { 
    let resultHandler = ResultHandler() 
    doSomethingAsynchronous(resultHandler.invokeCallbacks) 
    return resultHandler 
} 

अब आप इसे पसंद कॉल कर सकते हैं इस:

doRequest(input).success {result in 
    print("success, with:", result) 
}.failure { 
    print("fail :(") 
} 

केवल एक चीज नोट करने के लिए अपने doSomethingAsynchronous समारोह इसके पूरा होने के ब्लॉक मुख्य थ्रेड के लिए वापस प्रेषण करने के लिए, धागा सुरक्षा सुनिश्चित करना होगा है।


(उपयोग पर अतिरिक्त उदाहरण के साथ) पूर्ण परियोजना: https://github.com/originaluser2/Callback-Closure-Chaining

5

यह समझने के लिए कि क्या हो रहा है, यह "सुविधा" वाक्य रचना है, जो आप कोष्ठकों को छोड़ देता है बिना अपने कोड के पुनर्लेखन के लिए मदद मिलेगी, जब एक बंद एक समारोह के अंतिम पैरामीटर है में:

getListForID(12) 
    .Success({ /* Success block */ }) 
    .Failure({ /* Failure block */ }) 

  • getListForID की वापसी मान एक वस्तु
  • वस्तु दो समारोहकहा जाता है चाहिए होना चाहिए: यह इस एपीआई के पीछे कोड और अधिक स्पष्ट की संरचना बनाता है 0 और Failure*
  • दोनों Success और Failure बंद प्रकार की एक एकल पैरामीटर लेने की जरूरत
  • दोनों Success और Failure जरूरत self

* वस्तु केवल Success समारोह हो सकता था वापस जाने के लिए, और एक अलग ऑब्जेक्ट को एक Failure फ़ंक्शन के साथ वापस कर दें, लेकिन फिर आप Success और Failure हैंडलर को फिर से ऑर्डर करने में सक्षम नहीं होंगे, याड्रॉप करेंहैंडलर पूरी तरह से।

+0

इसके अलावा, एक संभावित कार्यान्वयन दो सरणी के लिए एक साधारण रैपर है - सफलता हैंडलर की एक सरणी और विफलता हैंडलर की एक सरणी, जब 'सफलता' और 'विफलता' विधियां केवल दिए गए सरणी में पैरामीटर जोड़ें। – Sulthan

+0

@ सुल्तान बिल्कुल! मैंने सिंटैक्स को समझाने की कोशिश की, बिना किसी विस्तार के * * सफलता 'और' विफलता 'विधियों के अंदर क्या होगा। दोनों विधियां एक तर्क के रूप में बंद हो जाएंगी; इन बंदियों के साथ क्या करना है विधि कार्यान्वयन तक है, हालांकि भविष्य के उपयोग के लिए अलग-अलग सरणी में बंद होने पर पूर्ण ज्ञान मिलता है। – dasblinkenlight