我有几个服务电话要求(1 GET和5个POST)。如果1 POST工作并且下一个问题发生,我想补偿/回滚/撤消第一个POST
因此,在下文中,如果func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CellRID") as! VideoAdsCell
let youtubeId = extractYoutubeIdFromLink(link: arrayVideo[indexPath.row].video)
if let url = URL(string: "http://img.youtube.com/vi/\(youtubeId!)/1.jpg") {
print(url)
UIImage.downloadFromRemoteURL(url, completion: { thumbnail,error in
guard let thumbnail = thumbnail, error == nil else {
print(error)
return
}
cell.imageForMain.image = thumbnail
cell.viewForMain.layer.masksToBounds = false
cell.viewForMain.layer.shadowOffset = CGSize(width: -1, height: 1)
cell.viewForMain.layer.shadowRadius = 1
cell.viewForMain.layer.shadowOpacity = 1
cell.viewForMain.layer.cornerRadius = 8
}
}
return cell
}
成功,我需要致电deleteFoo
,但insertFoo
至insertChild1
insertChild4
我一直试图将其分解为两个以进行理解,但每次我最终都会遇到杂乱无味的代码(但是在编辑之后它现在有效,但我对这种风格并不满意)
for {
barName <- barName()
f <- insertFoo(barName)
_ <- insertChild1(f.id) if f.id.isDefined
_ <- insertChild2(f.id) if f.id.isDefined
_ <- insertChild3(f.id) if f.id.isDefined
_ <- insertChild4(f.id) if f.id.isDefined
} yield f
P.S。也许猫有些东西(我们已经在这里和那里使用猫)
答案 0 :(得分:2)
您可以使用类型来表示操作的结果。以下for-comprehension将产生Future[Either[Exception, Foo]]
,它将是以下之一:
foo
失败Future[Left[Exception]]
,它将包含导致插入子节点失败的异常
foo
Future[Right[Foo]]
for {
barName <- barName()
f <- insertFoo(barName) if f.id.isDefined
res <- insertChildren(f).recoverWith(cleanUpFoo(f.id))
} yield res
private def insertChildren(f: Foo): Future[Either[Exception, Foo]] =
for {
_ <- insertChild1(f.id)
_ <- insertChild2(f.id)
_ <- insertChild3(f.id)
_ <- insertChild4(f.id)
} yield Right(f)
private def cleanUpFoo(id: Int)(e: Exception): Future[Either[Exception, Foo]] =
deleteFoo(id).map(_ => Left(e))