Scala スタイルの future と promise を使用すると、次のようなことができます。
let future: Future<[Listing]> = fetchListings().flatMap { listings in
listings.traverse { listing in
fetchUser(listing.userId).map { user in
listing.userName = "\(user.firstName) \(user.lastName)"
return listing
}
}
}
上記の式の結果は、値がリストの配列であるフューチャです。
上記の式が終了したら、リストのユーザー名を出力します。
future.onSuccess { listings in
listings.forEach {
print($0.userName)
}
}
Scala スタイルの future および promise ライブラリ: BrightFuturesまたはFutureLib
上記のライブラリのいずれかを試すためにプレイグラウンド ファイルに貼り付けることができる、すぐに使用できるコード例を以下に示します (FutureLib で動作しますが、BrightFutures はわずかな変更が必要になる場合があります)。
import FutureLib
import Foundation
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
class Listing {
let userId: Int
init(userId: Int) {
self.userId = userId
userName = ""
}
var userName: String
}
struct User {
let id: Int
let firstName: String
let lastName: String
init (_ id: Int, firstName: String, lastName: String) {
self.id = id
self.firstName = firstName
self.lastName = lastName
}
}
func fetchListings() -> Future<[Listing]> {
NSLog("start fetching listings...")
return Promise.resolveAfter(1.0) {
NSLog("finished fetching listings.")
return (1...10).map { Listing(userId: $0) }
}.future!
}
// Given a user ID, fetch a user:
func fetchUser(id: Int) -> Future<User> {
NSLog("start fetching user[\(id)]...")
return Promise.resolveAfter(1.0) {
NSLog("finished fetching user[\(id)].")
return User(id, firstName: "first\(id)", lastName: "last\(id)")
}.future!
}
let future: Future<[Listing]> = fetchListings().flatMap { listings in
listings.traverse { listing in
fetchUser(listing.userId).map { user in
listing.userName = "\(user.firstName) \(user.lastName)"
return listing
}
}
}
future.onSuccess { listings in
listings.forEach {
print($0.userName)
}
}