PromiseKit6が出てた
https://github.com/mxcl/PromiseKit
https://promisekit.org/news/2018/02/PromiseKit-6.0-Released/
まだ絶賛PromiseKit4使用中だったので、バージョンを上げましょうという話になった。
ご丁寧に上記URLでPromiseKit4からの変更について書かれている。
本記事では、バージョンアップのmigrationの際に主に変更があった部分のメモだけ載せるので、詳しくは上記を参照してください。
何か間違いあればご指摘お願いします
initializerが変わったので対応する
今まで
Promise { fulfill, reject in
if ... {
fulfill(data)
} else {
reject(error)
}
}
新しいやつ
Promise { resolver in
if ... {
resolver.fulfill(data)
} else {
resolver.reject(error)
}
// resolver.resolve(data, error) でもOK
}
resolver (公式ではseal) が引数として渡されるようになったのね。中身はそんなに変わってないけど、 resolver.resolve
で一気に渡せるようにもなってる。
then
が3つに別れたので対応する
今までthen
で一括りにされていたのが、次の3つに分解された。
元のthen
は次の3つがあった。
then(execute: Results<U>) -> Promise<U>
then(execute: Results<U>) -> AnyPromise
then(execute: Results<U>) -> U
AnyPromiseは置いておくとして、then
ひとつでPromiseを返すものとその値を返すものがあった。
また、多くの場合で何も値を返したくないこともあり、明示的に Promise<U> -> Void
と書いてやることでコンパイルエラーを回避する、ということをやっていたりした。(私だけだったら悲しい)
これらをわかりやすくするために次の3つができたっぽい。
- then
- done
- map
then
(新しい方)
Promiseを受け取ってPromiseを返すときに使う。今までどおり。
somePromise.then { obj -> Promise<U> in
doSomething(obj)
return getSomePromise()
}.then ...
done
Promiseを受け取って何も返却値がないときに使う。だいたいこれを使うことが多い。
promise.done { obj in
some(obj)
}
map
Promiseを受け取って中のvalueなどPromiseでない値を返すときに使う。
promise.map { obj -> U in
value = some(obj) // valueは非Promise
return value
}
その他の便利なやつ
他にも、上記の3つ+αなもののエイリアス的なメソッドが増えていた。
compactMap
map
のoptional unwrap付きバージョン。nil
だとcatch
に入る。
somePromise.compactMap { data in
UIImage(data: data)
}.done { image in
imageView.image = image
}.catch {
...
}
get
done
と同じで明示的にreturnしないが、与えられたものと同じ値を返す。
somePromise.get { data in
setup1(data)
}.done { data in
setup2(data)
}
tap
値を Result<T>
でラップした値を受け取る。catch
使えばいいんじゃないかと思うけど、何か用途があるんだろうか。
always
なくなってensure
になった
名前変わっただけ。
catch
がPromiseを返さなくなった
地味にやっかいなやつ。
catch
がPromiseを返さなくなったので、このあとに処理を続けられなくなった。
ensure
もダメ。
しかしまぁ、エラーのあとにやりたい処理があるでしょ、という場合のために finally
が追加された。
というわけで、catch
のあとにはfinally
を使う。
somePromise.done { data in
setData(data)
}.catch { e in
handleError(e)
}.finally {
finish()
}
Promiseを返すメソッドの最後がcatchになっていた場合ややこしい気がする。やってみて追記する。
新しい型 Guarantee<T>
ができたので使えそうなら使っていく
failしないPromiseとしてGuarantee<T>
ができた。
catch
が書けなくなるので、エラーになることのない処理はこっちになる。わかりやすい例のはafter
。
after(seconds: 1.0).done {
startAnimation()
} // .catchは書けない
エラー有り無しを制御しやすくて良い。UIKitのextensionにあった UIView.animate
系も Guarantee<Bool>
を返すようになっている(下記参照)。
UIViewのアニメーション
UIKitのextensionも同様に更新されていて、例えばアニメーションの書き方が少し変わっている。
https://github.com/PromiseKit/UIKit
大きな違いは、Promise<Bool>
ではなく Guarantee<Bool>
を返すようになっている点。
catchを書けなくなったので良い。
今まで
UIView.promise(animateWithDuration: 0.2, animation: {
someMove()
}).then {
...
}
新しい
UIView.animate(.promise, duration: 0.5, options: .curveLinear) {
someMove()
}.then { _ -> Guarantee<Bool> in
return UIView.animate(.promise, duration: 1.0, delay: 1.0, options: .curveEaseOut) {
anotherMove()
}
}.then {
...
調べる予定
時間切れなのでこのへんにしつつ、他にもなにかでてきたら調べて追記したい
例えば、
UIView.promise
にwarning消すために全部catch書くのが面倒UIView.animate
も変わってたので追記済み。