Проблема параллелизма с LiveData на Android - PullRequest
0 голосов
/ 17 сентября 2018

Я пытаюсь манипулировать данными, полученными из API, используя модификацию и LiveData.Ниже мой код

  viewModel.getTransactions("withdrawals").observe(this, Observer {
            if (it.getError() == null) {
                dataAdapter = ArrayList(it.getTransaction()?.data)
                if (dataAdapter.size == 0) {
                    // no withdrawal
                    withdrawSum = 0

                } else {
                    it.getTransaction()?.data?.forEachIndexed { _, element ->
                        withdrawSum += Math.abs(element.attributes.amount)
                    }

                }
            } else {
                // Error
            }
        })

viewModel.getTransactions("deposits").observe(this, Observer {
        if(it.getError() == null){
            dataAdapter = ArrayList(it.getTransaction()?.data)
            if(dataAdapter.size == 0){
                // no deposit
                depositSum = 0

            }else {
                it.getTransaction()?.data?.forEachIndexed{ _, element ->
                    depositSum+=Math.abs(element.attributes.amount)
                }

            }
        } else {
            // Error
        }

    })
    // difference will be 0 since deposit = 0 and withdrawal = 0
    difference = deposit - withdrawal

У меня возникла проблема с этой строкой difference = deposit - withdrawal.Это вызывается немедленно, в отличие от ожидания завершения вызовов дооснащения перед выполнением вычитания.Что я могу сделать, чтобы решить эту проблему?Ужасным решением было бы вложить код депозита в вывод 100 *, есть ли более чистое решение?

1 Ответ

0 голосов
/ 18 сентября 2018

Я решил проблему.

    val withdrawals = model.getTransactions("withdrawals")
    val deposits = model.getTransactions("deposits")
    zipLiveData(withdrawals, deposits).observe(this, Observer {
        if(it.first.getError() == null){
            dataAdapter = ArrayList(it.first.getTransaction()?.data)
            if (dataAdapter.size == 0) {
                // no withdrawal
                withdrawSum = 0
            }  else {
                it.first.getTransaction()?.data?.forEachIndexed { _, element ->
                    withdrawSum += Math.abs(element.attributes.amount)
                }
            }
        } else {
            // Error
        }
        if(it.second.getError() == null){
            dataAdapter = ArrayList(it.second.getTransaction()?.data)
            if (dataAdapter.size == 0) {
                // no deposit
                depositSum = 0
            }  else {
                it.second.getTransaction()?.data?.forEachIndexed { _, element ->
                    depositSum += Math.abs(element.attributes.amount)
                }
            }
        } else {
            // Error
        }
        difference = depositSum - withdrawSum
    })

Функция zipLiveData взята из здесь

fun <A, B> zipLiveData(a: LiveData<A>, b: LiveData<B>): LiveData<Pair<A, B>> {
    return MediatorLiveData<Pair<A, B>>().apply {
        var lastA: A? = null
        var lastB: B? = null

        fun update() {
            val localLastA = lastA
            val localLastB = lastB
            if (localLastA != null && localLastB != null)
                this.value = Pair(localLastA, localLastB)
        }

        addSource(a) {
            lastA = it
            update()
        }
        addSource(b) {
            lastB = it
            update()
        }
    }
}
...