簡體   English   中英

協程在其他 function 中等待任務與相同的 scope

[英]Coroutine waiting for task in other function with same scope

我有一個像這樣的 function 在帶有 rowId 的表中插入一個新行:

@Composable
fun AddNewCustomer() {
    val db = CustomersDatabase.getDatabase(LocalContext.current)
    val coroutineScope = rememberCoroutineScope()
    val createMainEntity = {
        coroutineScope.launch(Dispatchers.IO) {
            val rowId = db.customersDao().getLast()!!.id + 1
            db.customersDao().insertPrimaries(CustomersEntity(rowId, null, null, null))

        }
    }
    createMainEntity()
    otherFunc(db, coroutineScope)      
    
}

在另一個 function 中,我在另一個表中插入了一個新行:

@Composable
private fun otherFunc(
    db: CustomersDatabase,
    coroutineScope: CoroutineScope,
) {
        val save = {
                coroutineScope.launch(Dispatchers.IO) {
                    delay(100)
                    val rowId = db.customersDao().getLast()!!.id
                    db.customersDao().insertPhone(PhoneNumberEntity(phone = "", customerId = rowId , field = "" ))
   }
   }
        save()
}

我想 save() 在otherFunc等到 createMainEntity 完成,延遲,我可以確定createMainEntity首先完成,但這是一種骯臟的方式,我怎樣才能做得更好。

根據我對 Compose 的了解,這些函數絕對不應該是 Composables。 可組合 function 不得影響外部 state,因為它必須是冪等的。 您可以從您的其中一個 Composable 中的偵聽器 lambda 調用這些函數之一,但不能直接調用它們。

因此,按照慣例,function 名稱不應以大寫字母開頭。 我還在名稱中添加了“Async”以表示它異步執行某些操作(通過啟動單獨運行的協程)。

要在 Room 事務完成后調用另一個 function,請在執行事務的協程內調用它。

此外,創建一個 lambda function 只是為了立即調用它而不做任何其他事情,所以我刪除了它。 您固定的 function 看起來像:

fun addNewCustomerAsync(coroutineScope: CoroutineScope) {
    val db = CustomersDatabase.getDatabase(LocalContext.current)
    coroutineScope.launch(Dispatchers.IO) {
        val rowId = db.customersDao().getLast()!!.id + 1
        db.customersDao().insertPrimaries(CustomersEntity(rowId, null, null, null))
        createMainEntity() 
        otherFunc(db, coroutineScope) 
    }
}

您的其他 function 應該只是暫停 function。 不需要指定調度程序,因為它不調用任何阻塞函數。

private suspend fun otherFunc(db: CustomersDatabase) {
    delay(100) // Why are you doing this? Probably can remove this line.
    val rowId = db.customersDao().getLast()!!.id
    db.customersDao().insertPhone(PhoneNumberEntity(phone = "", customerId = rowId , field = "" ))
}

您可以在您的可組合函數之一中從偵聽器/回調調用addNewCustomerAsync() ,但不能直接調用它。 真的,這些與數據庫交互的 function 應該在 ViewModel 中,所以我會從addNewCustomerAsync()中刪除coroutineScope參數並讓它使用viewModelScope

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM