提供是否使协程关闭或取消?

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.