提供是否使协程关闭或取消?
Does offer make the coroutines close or cancelled?
我正在查看 Android 开发者网站上的流程文档,但我有一个问题。
https://developer.android.com/kotlin/flow#callback
如果你看上面的 link,你会看到这样的代码。
class FirestoreUserEventsDataSource(
private val firestore: FirebaseFirestore
) {
// Method to get user events from the Firestore database
fun getUserEvents(): Flow<UserEvents> = callbackFlow {
// Reference to use in Firestore
var eventsCollection: CollectionReference? = null
try {
eventsCollection = FirebaseFirestore.getInstance()
.collection("collection")
.document("app")
} catch (e: Throwable) {
// If Firebase cannot be initialized, close the stream of data
// flow consumers will stop collecting and the coroutine will resume
close(e)
}
// Registers callback to firestore, which will be called on new events
val subscription = eventsCollection?.addSnapshotListener { snapshot, _ ->
if (snapshot == null) { return@addSnapshotListener }
// Sends events to the flow! Consumers will get the new events
try {
offer(snapshot.getEvents())
} catch (e: Throwable) {
// Event couldn't be sent to the flow
}
}
// The callback inside awaitClose will be executed when the flow is
// either closed or cancelled.
// In this case, remove the callback from Firestore
awaitClose { subscription?.remove() }
}
}
上面代码中解释了awaitClose
是在协程关闭或取消时执行
但是,除了初始化 eventsCollection
.
的 try-catch 语句外,代码中没有 close()
此外,在 Android 开发者页面底部说 offer does not add the element to the channel and **returns false** immediately
。
我的问题是,在上面的代码中,执行offer(snapshot.getEvents())
时,协程是否与return false
取消,所以执行awaitClose
?
期望:
如文档所述:
When you try to add a new element to a full channel, send
suspends the
producer until there's space for the new element, whereas offer
does
not add the element to the channel and returns false
immediately.
因此:
如果不违反其容量限制,它会立即将指定的元素添加到此通道,并且 returns 是成功的结果。否则,returns 失败或关闭结果。这是 send 的同步变体,在发送挂起或抛出时退出。
所以当 trySend
调用 return 一个不成功的结果时,它保证该元素没有交付给消费者,它不会调用 onUndeliveredElement
为这个频道。有关处理未交付元素的详细信息,请参阅频道文档中的“Undelivered elements”部分。
结论:
onDeliveredElement
的典型用法是关闭正在通过通道传输的资源。以下代码模式保证即使生产者、消费者、and/or 通道被取消,打开的资源也会关闭。 资源永不丢失。所以不,它没有 return false
.
我正在查看 Android 开发者网站上的流程文档,但我有一个问题。
https://developer.android.com/kotlin/flow#callback
如果你看上面的 link,你会看到这样的代码。
class FirestoreUserEventsDataSource(
private val firestore: FirebaseFirestore
) {
// Method to get user events from the Firestore database
fun getUserEvents(): Flow<UserEvents> = callbackFlow {
// Reference to use in Firestore
var eventsCollection: CollectionReference? = null
try {
eventsCollection = FirebaseFirestore.getInstance()
.collection("collection")
.document("app")
} catch (e: Throwable) {
// If Firebase cannot be initialized, close the stream of data
// flow consumers will stop collecting and the coroutine will resume
close(e)
}
// Registers callback to firestore, which will be called on new events
val subscription = eventsCollection?.addSnapshotListener { snapshot, _ ->
if (snapshot == null) { return@addSnapshotListener }
// Sends events to the flow! Consumers will get the new events
try {
offer(snapshot.getEvents())
} catch (e: Throwable) {
// Event couldn't be sent to the flow
}
}
// The callback inside awaitClose will be executed when the flow is
// either closed or cancelled.
// In this case, remove the callback from Firestore
awaitClose { subscription?.remove() }
}
}
上面代码中解释了awaitClose
是在协程关闭或取消时执行
但是,除了初始化 eventsCollection
.
close()
此外,在 Android 开发者页面底部说 offer does not add the element to the channel and **returns false** immediately
。
我的问题是,在上面的代码中,执行offer(snapshot.getEvents())
时,协程是否与return false
取消,所以执行awaitClose
?
期望:
如文档所述:
When you try to add a new element to a full channel,
send
suspends the producer until there's space for the new element, whereasoffer
does not add the element to the channel and returnsfalse
immediately.
因此:
如果不违反其容量限制,它会立即将指定的元素添加到此通道,并且 returns 是成功的结果。否则,returns 失败或关闭结果。这是 send 的同步变体,在发送挂起或抛出时退出。
所以当 trySend
调用 return 一个不成功的结果时,它保证该元素没有交付给消费者,它不会调用 onUndeliveredElement
为这个频道。有关处理未交付元素的详细信息,请参阅频道文档中的“Undelivered elements”部分。
结论:
onDeliveredElement
的典型用法是关闭正在通过通道传输的资源。以下代码模式保证即使生产者、消费者、and/or 通道被取消,打开的资源也会关闭。 资源永不丢失。所以不,它没有 return false
.