我经常需要通过一系列链接的期货传递多个对象。我已经用类似于下面的代码解决了这个问题,但是感觉不对。有没有更好的方法来写这个?
尤其是,return map(to:
开头的行听起来不正确,因为我要获取实际值a
,然后将其转换为Future conn.future(a)
,以便稍后再次进行平面映射在下一步中。
在以下人为设计的示例中,我们正在创建一个A
,其中包含一个相关对象B
,并可选地创建一个与C
相关的B
,这就是为什么B
必须通过链传递。
class A {
id: Int?
}
class B {
id: Int?
aId: Int?
}
class C {
id: Int?
bId: Int?
}
/// Creates an A and B, with an optionally attached C. Returns the A.
func create(withC: Bool, on conn: MySQLConnection) throws -> Future<A> {
return try A.create(on: conn)
// Returning two futures
.flatMap(to: (A, B).self) { a in
let futureB = try B(aId: a.requireID()).create(on: conn)
return map(to: (A, B).self, conn.future(a), futureB) { ($0, $1) }
}
// Returning two futures, one optional
.flatMap(to: (A, C?).self) { a, b in
guard withC else {
return map(to: (A, C?).self, conn.future(a), conn.future(nil)) { ($0, $1) }
}
let futureC = try C(bId: b.requireId()).create(on: conn)
return map(to: (A, C?).self, conn.future(a), futureC) { ($0, $1) }
}
// Convert back to the future we care about
.map(to: A.self) { a, _ in return a }
}