代码之家  ›  专栏  ›  技术社区  ›  StuartDTO

如何等到一大堆电话结束后再打另一个电话

  •  0
  • StuartDTO  · 技术社区  · 5 年前

    我正在使用 RxJava 我知道 concat ,我想它确实适合我,因为我想先完成第一个调用,然后再执行第二个调用,但我不知道如何实现它。

    private fun assignAllAnswersToQuestion(questionId: Long) {
    
            answerListCreated.forEach { assignAnswerToQuestion(questionId, it.id) }
    
        }
    
        private fun assignAnswerToQuestion(questionId: Long, answerId: Long) {
            disposable = questionService.addAnswerToQuestion(questionId,answerId,MyUtils.getAccessTokenFromLocalStorage(context = this))
            .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(
                    {
                        result -> //Do nothing it should call the next one
    
                    },
                    { error -> toast(error.message.toString())}
                )
        }
    

    但是,一旦这一切都结束了 forEach 我想这样做:

    private fun assignAllAnswersToQuestion(questionId: Long) {
    
       answerListCreated.forEach { assignAnswerToQuestion(questionId, it.id) 
       anotherCallHere(questionId) //Do it when the first forEach is finished!!
    
    }
    

    还有,这是一种通过协同程序实现的方法吗?

    0 回复  |  直到 5 年前
        1
  •  1
  •   gpunto    5 年前

    我想你必须这么做 .map 你的名单( answerListCreated )一系列 Flowable s、 然后使用 Flowable.zip
    zip 流动的 这是一个单一的结果。既然你不需要这些结果,我们就忽略它们。
    之后 拉链 结束了,你可以 .flatMap 执行下一个调用(假设 anotherCallHere .

    val flowableList = answerListCreated.map { assignAnswerToQuestion(questionId, it.id) }
    
    disposable = Flowable.zip(flowableList) { /* Ignoring results */ }
        .flatMap { anotherCallHere(questionId) }
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            // ...
        }
    

    应该注意的是,如果任何调用失败,整个链都将失败( onError 将被调用)。

        2
  •  0
  •   Mike Simpson    5 年前

    您可以为此使用协同程序runBlocking{}。

    private fun assignAllAnswersToQuestion(questionId: Long) = launch {
        runBlocking {
            answerListCreated.forEach { assignAnswerToQuestion(questionId, it.id) }
        }
        anotherCallHere(questionId)
    }
    
    private fun assignAnswerToQuestion(questionId: Long, answerId: Long) = launch (Dispatchers.IO) {
        questionService.addAnswerToQuestion(
            questionId,
            answerId,
            MyUtils.getAccessTokenFromLocalStorage(context = this)
        )
    }
    

    请注意,我已使这两个函数将其代码包装在一个启动{}块中。 为了能够像这样调用launch{},您可能需要实现您的类 CoroutineScope

    class MyActivityOrFragment: Activity(), CoroutineScope {
        lateinit var job = SupervisorJob()
        private val exceptionHandler =
            CoroutineExceptionHandler { _, error ->
                toast(error.message.toString()
            }
        override val coroutineContext = Dispatchers.Main + job + exceptionHandler
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            job = Job()
        }
    
        override fun onDestroy() {
            super.onDestroy()
            job.cancel()
        }
    
        ...
    }