首页 > 解决方案 > 等待数据库插入,Kotlin 协程

问题描述

我有一门课(Repo)正在做一些 Room DB 和一些改造电话。对于Retrofit我正在使用的电话RxRoom我正在使用的Coroutine.

现在问题出在单击按钮上,我必须同时执行 DB 和 API 调用。

  1. 更新数据库中的一些报告
  2. 在服务器上上传图像
  3. 报告发送到服务器
  4. 更新数据库中的报告

由于 RX 和 Coroutine 的混合,我无法进行一些顺序调用。如上所述,步骤必须是顺序的。但是第一步需要时间来执行,因此会覆盖最后一步的数据。

我想确保在做其他事情之前完成第一步。

这是我正在使用的一些代码

fun submit(
    report : Report,
    images: List<Image>,
    comment: List<Comments>
): Completable {

   var completable: Completable

    runBlocking {
    roomRepo.saveReport(report, images, comment)
   }
      /////////////// Here I need to wait for the above to finish

        val analysisImageList = uploadImages(images)

        completable = myAPi.putAnalysisList(analysisResponse).doOnComplete {
            roomRepo.updateReportStatus(report.id, Pending)
        }.applyNetworkSchedulersCompletable()

    return completable
}

也,这saveReport看起来像

suspend fun saveReport(
    report : Report,
    images: List<Image>, comment: List<Comments>
) {
    reportDao.insertReportCard(report) /// insertReportCard() is a suspend function

    for (image in images) {
        image.projectId = report.uuid
        imageDao.insertImage(image) /// insertImage() is a suspend function
    }

    comment ?: return
    for (coment in comment) {
        hotspotCommentDao.
insertHotspotComments(coment) /// insertHotspotComments() is a suspend function
    }
}

标签: androidkotlinkotlin-coroutines

解决方案


可能已经有一个库(不确定),但是您可以创建一个将 Completables 转换为协程的函数,以便您可以在协程流程中使用它们。此函数挂起,直到blockingAwait()调用在某个后台线程上返回。

suspend fun Completable.await() = withContext(Dispatchers.Default) {
    blockingAwait()
}

然后你的submit函数可以是一个挂起函数,所以你可以在协程中使用它:

suspend fun submit(
    report : Report,
    images: List<Image>,
    comment: List<Comments>
) {
    roomRepo.saveReport(report, images, comment)
    val analysisImageList = uploadImages(images)

    myAPi.putAnalysisList(analysisResponse).doOnComplete {
        roomRepo.updateReportStatus(report.id, Pending)
    }
        .applyNetworkSchedulersCompletable()
        .await()
}

推荐阅读