Мне часто нужно пропустить несколько объектов через ряд связанных Фьючерсов. Я решил проблему с кодом, похожим на приведенный ниже, но он не кажется «правильным». Есть ли лучший способ написать это?
В частности, строки, начинающиеся с return map(to:
, не имеют правильного запаха, поскольку я беру фактическое значение a
, а затем превращаю его в будущее 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 }
}