請參考 PromiseKit 的文件:
Promise 基本概念
在非同步執行的流程處理上,傳統作法一直是個麻煩點,
而 Promise 透過一些函式可以很直覺的管理非同步的流程。
傳統的做法
以 iOS 而言,你可能要透過 NSOperationQueue
或者
GCD (Grand Central Dispatch)
這些方法來做非同步的流程。
如果要接續觸發( A 事情做完做 B )的情境,A 事情的 callback 做完之後緊接著 B 事情,你可能會得到一個很深的縮排。
如果是互相等待完成( A 跟 B 事情 )的情境,你可能要透過一些 boolean 來把狀態記住,然後 A 事情跟 B 事情的 callback 同時要檢查對方是否做完,才接續另外一個 callback 。 以上並不是說這樣寫不能用,只是你會有更好的解法,讓程式碼變得更乾淨好閱讀。
Promise 的做法
主要關鍵字有 firstly
then
catch
還有 always
。
要字面上來看就是 「首先」、「然後」最後是有錯誤時用 catch
抓取錯誤。
這個範例還用了一個很實用的 when()
來綜合二件非同步的事情,當二件事情都結束時才會回傳到下一個 Callback。
這是一個綜合各種基本關鍵字的範例
firstly {
// Show Loading status bar
return when(myAsnycTaskA(), myAsnycTaskB())
}.then { (resultA:MyObjectA, resultB:MyObjectB) -> Void in
// Show results
}.always {
// Hide Loading status bar
}.catch { error in
print(error)
}
最簡單的範例
這是一個最基本的範例
基本句型有 then
跟 catch
就可以了
myAsnycTaskA().then {
(resultA:MyObjectA) -> Void in
// Show results
}.catch { error in
print(error)
}
宣告
至於你想要宣告一個事情也不難
func myAsnycTaskA()-> Promise<MyObjectA> {
return Promise { fulfill, reject in
// Done
fulfill(result)
// Fail
reject(error)
}
}
回傳一個 Promise,裡面有 fulfill()
跟 reject()
二個 method。
當資料回來的時候呼叫 fulfill()
,
當出現錯誤的時候呼叫 reject()
並帶入一個 Error 物件。
複雜一點的範例
這時回過頭來看第一個範例,我又把它改複雜了一點,是不是比較不難了呢?
firstly {
// Show Loading status bar
return when(myAsnycTaskA(), myAsnycTaskB())
}.then { (resultA:MyObjectA, resultB:MyObjectB) -> Promise<MyObjectC> in
// So some processing
return myProcessingTaskC()
}.then { (resultC:MyObjectC) -> Void in
// Show results
}.always {
// Hide Loading status bar
}.catch { error in
print(error)
}
首先,同時做 myAsnycTaskA()
跟 myAsnycTaskB()
等二者結果回傳了之後,做 myProcessingTaskC()
最後回傳結果。
在 callback 的處理上是不是變得比較開心愉快了一點呢?
以上就是 Promise 的快速介紹。
有興趣的話,可以查看官方文件裡面有更進階的寫法。
這個概念不只在 iOS (Swift) 可以用,在 JavaScript (ES6) 也有類似的語法,有機會再專文介紹。