我正在尝试连续运行两个协程启动。我怎样才能存档这个?
第一个尝试获取持续时间。当成功时,收集应该停止,并且我的协程中的第二次启动应该运行。
我不知道这是否是正确的方法。但我需要先获取 Duration,然后处理第二部分。
仅此部分即可工作。但不能一起,因为收集是阻塞的。我也尝试过 return@collect,但不起作用
@Singleton
class AddDayReminderNotification(
private val notificationUseCases: NotificationUseCases,
private val dayUseCases: DayUseCases,
private val weekUseCases: WeekUseCases,
private val settingsUseCases: SettingsUseCases
) {
suspend fun addNotification(context: Context?, notification: Notification) {
var neededDuration: Duration = Duration.ZERO
val dayOfWeekIndex = getDayOfWeekLocalized(notification.date)
coroutineScope {
val dayDuration = launch {
weekUseCases.getAllWeeks()
.collect { weekResponse ->
when (weekResponse) {
is Response.Failure -> {
coroutineContext.cancel()
}
is Response.Loading -> {}
is Response.Success -> {
val week =
weekResponse.data?.firstOrNull {
it.week == getWeekOfYearByLocalDate(
notification.date
) && it.year == notification.date.year
}
if (week != null) {
val stringValue = week.weekDailyDurations
val splitString = stringValue.split(":")
val intList: MutableList<Int> = mutableListOf()
if (splitString.count() == 7) {
splitString.forEach {
try {
intList.add(it.toInt())
} catch (e: NumberFormatException) {
println("Error: $it is not a valid integer")
coroutineContext.cancel()
}
}
}
neededDuration = intList[dayOfWeekIndex].minutes
} else {
settingsUseCases.getSetting(SettingsIndex.WeekDailyDurations.getIndex())
.collect { response ->
when (response) {
is Response.Failure -> {
coroutineContext.cancel()
}
is Response.Loading -> {}
is Response.Success -> {
val stringValue = response.data?.stringValue
if (stringValue.isNullOrEmpty()) {
coroutineContext.cancel()
} else {
val splitString = stringValue.split(":")
val intList: MutableList<Int> =
mutableListOf()
if (splitString.count() == 7) {
splitString.forEach {
try {
intList.add(it.toInt())
} catch (e: NumberFormatException) {
println("Error: $it is not a valid integer")
coroutineContext.cancel()
}
}
}
neededDuration = intList[dayOfWeekIndex].minutes
}
}
}
}
}
}
}
}
}
val notificationCreator = launch {
if (neededDuration != Duration.ZERO) {
dayUseCases.getAllDays()
.collect { dayResponse ->
when (dayResponse) {
is Response.Failure -> {
coroutineContext.cancel()
}
is Response.Loading -> {}
is Response.Success -> {
if (dayResponse.data != null) {
val foundDay =
dayResponse.data.firstOrNull { it.date == notification.date && it.isActive }
if (foundDay == null) {
notificationUseCases.getAllNotifications()
.collect { notificationResponse ->
when (notificationResponse) {
is Response.Failure -> {
coroutineContext.cancel()
}
is Response.Loading -> {}
is Response.Success -> {
if (notificationResponse.data != null) {
val dayReminderNotification =
notificationResponse.data.firstOrNull { it.date == notification.date && it.notificationType == NotificationType.DayUnchangedReminder.value }
if (dayReminderNotification == null) {
notificationUseCases.upsertNotification(
notification
)
context?.let {
DayReminderNotificationService(
it
)
}
?.showNotification(
notification.title + neededDuration.toFloatHours(),
notification.description,
notification.notificationType
)
}
coroutineContext.cancel()
}
}
}
}
}
coroutineContext.cancel()
}
}
}
}
} else {
coroutineContext.cancel()
}
}
}
}
}
要解决这个问题,关键是要正确管理协程的流程。具体来说,您希望仅在第一个协程成功完成后才启动第二个协程。由于collect是一个挂起函数,它会阻塞当前协程直到完成。因此,依次启动两个协程将无法按预期工作,因为第二个协程可能会在第一个协程完成之前启动。
为了实现您正在寻找的目标,您可以在第一部分使用 async (获取持续时间)并使用 wait() 等待结果,然后再继续第二个协程。
val dayDurationDeferred = async {
weekUseCases.getAllWeeks()
.collect { weekResponse ->
// Your existing code for getting neededDuration
}
}
// Wait for the first coroutine to complete before proceeding
dayDurationDeferred.await()
// Then proceed with the second part
val notificationCreator = launch {
if (neededDuration != Duration.ZERO) {
dayUseCases.getAllDays()
.collect { dayResponse ->
// Your existing code for processing notifications
}
} else {
coroutineContext.cancel()
}
}
需要改变:
对第一个协程使用异步:
异步构建器允许您启动协程并获取可等待稍后获取结果的延迟对象。 收集块将异步执行,但您可以通过在结果上等待()来控制流程,然后再继续第二个协程。
等待结果:
dayDurationDeferred.await() 确保第一部分(获取持续时间)完成,然后再继续处理通知的第二个协程。
请告诉我这是否对您有帮助。