我們一般會監(jiān)聽文本變化,文本變化后就發(fā)起搜索請求峻汉。
但現(xiàn)在有兩個問題
1. 毫無意義的中間搜索
比如用戶快速輸入123456789,我們希望只發(fā)起一次請求123456789,而不是發(fā)起9次請求(每次變化都發(fā)起請求)喉刘,我們可以使用sample操作符
2.請求和響應(yīng)順序不一致導(dǎo)致顯示的結(jié)果有誤
比如我們先搜索123再搜索456,按照正常順序123的搜索結(jié)果先返回漆弄,456的搜索結(jié)果后返回睦裳,頁面最終顯示456的搜索結(jié)果,沒毛病撼唾。
但如果先返回456的搜索結(jié)果廉邑,再返回123的搜索結(jié)果,就會出現(xiàn)123的搜索結(jié)果覆蓋456的搜索結(jié)果倒谷,結(jié)果就是錯的蛛蒙。解決方法是mapLatest操作符。
代碼如下
class MainActivity : AppCompatActivity() {
private val _search = MutableStateFlow("")
private lateinit var content: TextView
private lateinit var editText: EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
content = findViewById(R.id.content)
editText = findViewById(R.id.search)
lifecycleScope.launch {
_search.sample(500)
.filter {
it.isNotEmpty()
}
.mapLatest {
map(value = it)
}.collect {
Log.d("TAG", "收到了結(jié)果 $it")
content.text = it
}
}
editText.addTextChangedListener {
_search.value = it.toString()
}
}
private var current = 5
private suspend fun map(value: String): String = withContext(Dispatchers.IO) {
Log.d("TAG", "發(fā)起了請求 $value ,delay = $current")
delay(current * 1000L)
current -= 3
if (current <= 0) {
current = 5
}
value
}
}