首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

kotlin协程,为什么在添加Log语句后调用await()时,async {}返回延迟返回不同的值

Kotlin协程是一种用于异步编程的框架,它允许开发者以顺序的方式编写异步代码,使得代码更加简洁和易于理解。在使用协程的过程中,我们经常会遇到添加Log语句后调用await()时,async{}返回延迟返回不同的值的情况。

这个问题通常是由于协程的执行方式导致的。在Kotlin协程中,async{}函数会立即启动一个协程并返回一个Deferred对象,该对象包含协程的计算结果。当我们调用await()函数时,它会等待协程执行完成并返回计算结果。

然而,当我们在async{}函数中添加了Log语句后调用await()函数时,可能会触发以下两种情况导致延迟返回不同的值:

  1. Log语句导致协程执行时间延长:添加Log语句会导致协程执行的时间增加,可能会导致await()函数在协程完成之前被调用,从而返回的结果是未完成的值。为了解决这个问题,我们可以将Log语句移动到await()函数之后,确保在获取结果之前不会进行其他操作。
  2. Log语句导致协程切换:协程的执行是通过协程调度器来管理的,当协程遇到挂起点时,调度器会将其切换到其他可执行的协程。添加Log语句可能会导致协程切换,从而延迟返回不同的值。为了解决这个问题,我们可以使用runBlocking{}包裹整个代码块,以确保在协程执行完成之前不会发生切换。

需要注意的是,以上解决方法只是针对常见情况的一种解释,具体问题的解决方法可能因情况而异。此外,对于Kotlin协程的更多详细信息和用法,您可以参考腾讯云的相关产品文档和示例代码,以了解如何在腾讯云环境中使用Kotlin协程进行开发。

腾讯云相关产品介绍链接:

  • 腾讯云Kotlin SDK:腾讯云提供的Kotlin SDK,方便开发者在Kotlin中调用腾讯云的各类服务。
  • 腾讯云函数计算:腾讯云提供的无服务器计算服务,支持使用Kotlin开发无服务器函数。
  • 腾讯云容器服务:腾讯云提供的容器化部署和管理服务,支持使用Kotlin进行容器应用开发。

以上是对于"kotlin协程,为什么在添加Log语句后调用await()时,async {}返回延迟返回不同的值"这个问题的解答,希望能对您有所帮助。如果您有其他问题,还请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Kotlin 】Flow 异步流 ① ( 以异步返回返回多个返回 | 同步调用返回多个弊端 | 尝试 sequence 中调用挂起函数返回多个返回 | 调用挂起函数返回集合 )

文章目录 一、以异步返回返回多个返回 二、同步调用返回多个弊端 三、尝试 sequence 中调用挂起函数返回多个返回 四、调用挂起函数返回集合 一、以异步返回返回多个返回 ----... Kotlin Coroutine 中 , 使用 suspend 挂起函数 以异步方式 返回单个返回肯定可以实现 , 参考 【Kotlin 挂起和恢复 ① ( 挂起和恢复概念...| suspend 挂起函数 ) 博客 ; 如果要 以异步方式 返回多个元素返回 , 可以使用如下方案 : 集合 序列 Suspend 挂起函数 Flow 异步流 二、同步调用返回多个弊端...sequence 中调用挂起函数返回多个返回 ---- 尝试使用 挂起函数 kotlinx.coroutines.delay 进行休眠 , 这样挂起 , 不影响主线程其它操作 , 此时会报如下错误...---- 如果要 以异步方式 返回多个返回 , 可以调用挂起函数返回集合 , 但是该方案只能一次性返回多个返回 , 不能持续不断 先后 返回 多个 返回 ; 代码示例 : package

8.3K30

Kotlin 学习笔记(四)—— 基础知识,面试官最爱了~

这也是为什么我们可以中用写同步代码思想,去写异步逻辑。...再来看下不同启动模式,有四种: DEFAULT:默认,表示创建,立即开始调度,执行前如果被取消则直接进入取消响应状态; LAZY:表示该只有主动调用 start 或 join 或...; UNDISPATCHED:表示创建立即在当前函数调用栈中执行,是运行在创建所在线程。...().name}") "task2 返回" } Log.d("TAG", "task1 返回:${task1.await()} task2 返回:${task2...这是因为 await 函数也是一个挂起函数,执行到 await 时会被挂起,当 async 执行完返回结果,才会继续执行。

1.5K30
  • RxHttp ,比Retrofit 更优雅体验

    filter、distinct、sort等30余个操作符来执行不同业务逻辑,本文后续会一一介绍 第三步,最后,只需调用await、tryAwait、awaitResult这三个中任一操作符获取返回即可...直接用到自己项目上,如ResponseParser解析器,只需要改下if语句判断条件即可 2.4、操作符介绍 awaitResult 返回kotlin.Result awaitResult是最常用字符...delay、startDelay 延迟 delay操作符是请求结束延迟一段时间返回;而startDelay操作符则是延迟一段时间再发送请求,如下: val student = RxHttp.postForm...() 以上代码正常情况下,都能正确拿到返回为什么?...亦或者说,我对不是很懂,你只要保证安全前提下,告诉怎么用就行了,ok,那下面如何安全开启一个,做到自动异常捕获,且页面销毁,自动关闭及请求 4、开启及关闭 ========= 对于开启

    2.2K20

    【翻译】深入 Kotlin

    调用 Job 类 join() 方法将暂停它所包含运行。 async{} 通过使用 async 函数你可以达到和 launch 一样效果,唯一一个非常重要差别是:它有返回。...).await() showUserData(user) } 现在我们知道了如何获取执行返回,但是如果我们需要多个返回呢?... C# 中 asyncawait 都是关键字 C# 中 async 函数只能返回一个 Task 实例或者返回空 如果你仔细观察这个例子,你会看到 Kotlin 中, launch{}...通过使用 CoroutineStart.LAZY 这个,可以让开发者显式调用返回 Deferred 实例或者 Job 实例 await() 方法或者 join() 方法才开始运行。...这个 await 函数返回类型参数 T 现在是 continuation 里类型参数了。结尾返回签名 Any 是用于控制运行流程。

    1.4K10

    Kotlin系列(三)

    LAZY:只有被需要,包括主动调用start,join,await等函数才会开始调度,如果调度前被取消协就会进入异常结束状态 UNDISPATCHED:创建之后立即在当前函数调用栈中执行...async和launch函数不同点在于launch函数启动是没有返回,而async函数启动是有返回。...launch函数和async函数唯一区别就是async函数启动返回,如果不需要获取执行结果,那么没必要用async函数。...context指定调度器上运行,并且它会返回体当中返回,它作用几乎和async{}.await()等价,但和async{}.await()相比,它内存开销更低,因此对于使用async立即要调用...,得到想要结果要更新UI又可以切换到UI线程上,非常方便。

    26710

    Kotlin实现原理:挂起与恢复

    之前文章中提及到suspend关键字,它一个作用是代码调用时候会为方法添加一个Continuation类型参数,保证中Continuaton上下传递。...所以首次运行label为0,进入case 0:语句。此时会记录现场为可能被挂起状态做准备,并设置下一个可能被执行状态。...所以只有当a方法返回COROUTINE_SUSPENDED才会执行if内部语句,跳出方法,此时就被挂起。当前线程也就可以执行其它逻辑,并不会被挂起所阻塞。...所以挂起代码层面来说就是跳出执行方法体,或者说跳出当前状态机下对应状态,然后等待下一个状态来临时进行执行。 那为什么说我们写这个a方法不会被挂起呢?...进入case: 0输出async start,调用async并通过await来挂起当前,再挂起过程中记录当前挂起点数据,并将lable设置为1。

    2.2K10

    Kotlin解析系列(上):调度与挂起

    async 创建一个新,不会阻塞当前线程,必须在作用域中才可以调用,并返回Deffer对象。可通过调用Deffer.await()方法等待该子执行完成并获取结果。...区别在于:async返回是Deferred对象,可通过Deffer.await()等待执行完成并获取结果,而 launch 不行。常用于并发执行-同步等待和获取返回情况。...3.2 Deferred Deferred继承自Job,具有与Job相同状态机制。 它是async构建返回一个任务,可通过调用await()方法等待执行完成并获取结果。...前述示例中async启动,也会调用其invokeSuspend方法执行async,假设async 返回结果已经可用时,即非 COROUTINE_SUSPENDED ,此时 completion...Deferred继承自Job,是async构建返回一个任务,可通过调用await()方法等待执行完成获取结果。

    1.9K40

    《Kotin 极简教程》第9章 轻量级线程:(2)《Kotlin极简教程》正式上架:

    不同之处在于, launch返回一个任务Job对象, 不带任何结果;而async返回一个延迟任务对象Deferred,一种轻量级非阻塞性future, 它表示后面会提供结果。...,而不阻塞线程;如果延迟任务完成, 则返回结果或引发相应异常。...9.10 通道 延迟对象提供了一种程之间传输单个方法。而通道(Channel)提供了一种传输数据流方法。...而线程阻塞代价通常是昂贵,尤其高负载,阻塞其中一个会导致一些重要任务被延迟。 另外,挂起几乎是无代价。不需要上下文切换或者 OS 任何其他干预。...挂起,对应状态与局部变量等一起被存储在编译器生成字段中。恢复该,恢复局部变量并且状态机从挂起点接着后面的状态往后执行。

    1.2K20

    Kotlin 程之Practice

    Kotlin 作用 让线程主动释放CPU是一个作用,一个执行挂起,然后让另一个执行, 等到这个协执行完毕再让前一个继续执行。...// runBlocking 和 coroutineScope 主要不同之处在于后者等待所有的子执行完毕并没有使当前线程阻塞     private fun testCoro() = runBlocking...,可以追踪一个job引用,并手动启动一个单独延迟取消追踪,     // 但这里会抛出一个TimeoutCancellationException异常     private fun showTwo...,与其他一起并发工作,与launch启动不同,launch启动返回一个Job对象     // 不带有任何返回,而async返回一个Defrred对象一个轻量级非阻塞future,使用await...挂起,它将完全由所运行线程中恢复挂起函数,     //非受限调度器是合适,它在没有消耗CPU时间或共享数据被限制指定线程中     fun testDispatcherMain() =

    1.2K20

    笔记

    Kotlin中文文档解释是轻量级线程,Go、Python 等很多现成语言语言层面上都实现,不过Kotlin和他们不同是,Kotlin本质上只是一套基于原生Java线程池 封装,...start() } 运行效果如下: image.png 可以看到当设置延迟加载是start()才开始执行 说到延迟加载,总结一下启动模式 DEFAULT 模式 默认 启动模式..., 执行到 第一个挂起点 之前 , 如果取消协 , 则不进行响应取消操作 ; LAZY 模式 创建 , 不会马上开始调度执行 , 只有 主动调用 start , join , await...方法 , 才开始调度执行 , 如果在 调度之前取消协 , 该直接报异常 进入异常响应状态 ; UNDISPATCHED 模式 创建,立即在当前函数调用栈执行任务,直到遇到第一个挂起函数...当 async 开启为根 或 supervisorScope 直接子,异常在调用 await 抛出,使用 try catch 可以捕获异常: fun main() = runBlocking

    86430

    Kotlin | 使用手册(不间断更新)

    注意 概念上,async 就类似于 launch。它启动了一个单独,这是一个轻量级线程并与其它所有的一起并发工作。...不同之处在于 launch 返回一个 Job 并且不附带任何结果,而 async 返回一个 Deferred —— 一个轻量级非阻塞 future, 这代表了一个将会在稍后提供结果 promise...async 我们可以通过更改 async 属性来实现惰性模式,在这个模式下,只有通过 await 或者 async返回 job.start,才会启动 注意:如果直接调用await,那么结果将会是顺序执行...,将直接运行在当前线程 子 当一个被其他 CoroutineScope 启动,它将通过 CoroutineScope.CoroutineContext 来承袭上下文,并且这个新将成为父子作业...而当我们调用了 delay之后,直接挂起,此时我们main函数中 coroutineContext 即为默认null,于是get为null 异步流 挂起函数可以异步返回单个,而如何返回多个计算好

    2.4K20

    Kotlin | 关于异常处理,你想知道都在这里

    如果我们初始化 scope 添加了 SupervisorJob ,那么整个scope对应所有 根 都将默认携带 SupervisorJob ,否则就必须在 CoroutineContext 显示携带...---- Tips 为什么上述 async 里要添加 SupervisorJob() ,这里再做一个解释。...()} val asyncB = async xxx } 因为 async 内部也是新作用域,如果 async 对应是根,那么我们可以 await() 直接捕获异常。...asyncA.await() asyncB.await() } } 但如果 async 其对应不是根(即不是 scope直接.async ),则会先将异常传递给父,从而导致异常没有调用处暴漏...如果此时我们为其增加 SupervisorJob() ,则标志着其不会主动传递异常,而是由该自行处理。所以我们可以调用处(await()) 捕获。

    88820

    饿了么资深Android工程师带你领略Kotlin力量

    第一个是可控制,不同于线程能做到可被控制发起子任务;第二个是轻量级,非常小、占用资源比线程还少,JVM平台上它本质就是一次方法调用;第三个是语法糖,目前能够使用语言都提供了很好语法糖支持...Kotlin中如果函数函数体内只有一个语句,那么就可以将这条语句直接赋值给函数声明。另外如果方法只有一个参数且该参数为lambda表达式时候,可以将函数小括号省略掉。...第三种是async/await,它不仅可以启动,还可以得到执行结果。 ? 这是前面示例中细分两个函数调用。因为前两个方式都是耗时操作,所以要放在子线程中运行。...这个对象扩展形式就是图中展示,可以看到它被静态添加了个await扩展方法,这个await就是一个方法和之前所提到await并无差别。 ?...上图代码中当网络请求被执行完之后会得到一个Call对象,通过调用await方法就能够获取到请求返回。 ? 这是扩展方法具体实现,整个函数只有一个函数体,内部启动了一个

    2.4K51

    深入理解JS事件循环

    setTimeout任务存到哪了 首先要清楚,任务队列不止有一个,Chrome还维护着一个延迟任务队列,这个队列维护了需要延迟执行任务,所以当你通过Javascript调用setTimeout,渲染进程会将该定时器回调任务添加延迟任务队列中...接下来咱们就来深入了解下async/await为什么能这么牛逼。...由于foo函数是被async标记过,所以当进入该函数时候,JavaScript 引擎会保存父调用栈等信息,然后切换到子,执行foo函数中console.log(1)语句,并打印出 1。...并且还会把这个新创建Promise返回给父拿到主线程控制权,首先调用newPromise.then,把回调函数放入到Promise中,这个回调函数是什么?...其实就是相当于生成器函数next(),调用这个回调函数会调用next(),会将父控制权再交给子。 接下来继续执行父流程,这里执行console.log(3),并打印出来3。

    4K60

    使用kotlin提高app性能(译)

    是一种并发设计模式,您可以Android上使用它来简化异步执行代码。Kotlin1.3版本添加了 Coroutines,并基于其他语言既定概念。...某些情况下,Kotlin可能会在暂停和恢复将执行移动到另一个线程。 这意味着线程局部变量可能不会指向整个withContext()块相同。...async启动一个新协同程序,并允许您使用名为await挂起函数返回结果。 通常,您应该从常规函数启动新,因为常规函数无法调用等待。...由于async期望某个时刻最终调用await,它会保留异常并在await调用中重新抛出它们。 这意味着如果您使用await从常规函数启动新协同程序,则可能会以静默方式删除异常。...通过每个延迟引用上调用await(),我们保证返回之前两个异步操作都完成: suspend fun fetchTwoDocs() = coroutineScope { val deferredOne

    2.3K10

    (建议收藏)关于JS事件循环, 这一篇就够啦

    setTimeout任务存到哪了 首先要清楚,任务队列不止有一个,Chrome还维护着一个延迟任务队列,这个队列维护了需要延迟执行任务,所以当你通过Javascript调用setTimeout,渲染进程会将该定时器回调任务添加延迟任务队列中...接下来咱们就来深入了解下async/await为什么能这么牛逼。...要让gen执行,需要通过调用gen.next()。 当正在执行时候,可以通过yield关键字来暂停gen执行,并返回主要信息给父。...由于foo函数是被async标记过,所以当进入该函数时候,JavaScript 引擎会保存父调用栈等信息,然后切换到子,执行foo函数中console.log(1)语句,并打印出 1。...并且还会把这个新创建Promise返回给父拿到主线程控制权,首先调用newPromise.then,把回调函数放入到Promise中,这个回调函数是什么?

    1.5K31

    浏览器原理学习笔记04—浏览器中页面事件循环系统

    延迟队列: Chrome 中还有另外一个消息队列维护了需要延迟执行任务列表,当通过 JavaScript 创建定时器,渲染进程会将该定时器回调任务添加延迟队列中。...使用 es7 async/await 可以实现用同步代码风格来编写异步代码,async/await 基础技术使用生成器()和 Promise(微任务) 来实现。...,需要通过调用 gen.next 来执行,执行时候可以通过 yield 关键字来暂停并返回关键字后面的内容给父,可以通过 return 结束当前并将 return 内容返回给父。...gen 和父主线程上交互执行(非并发执行),通过 yield 和 gen.next 来配合完成调用切换。...从视角观察代码整体执行流程,执行 await 100 语句时会默认创建一个 Promise 对象,然后 JavaScript 引擎会暂停当前 foo ,将主线程控制权转交给父,同时将创建

    1.6K168

    WeeklyPEP-8-PEP 492-使用 asyncawait 语法-overview

    重构这些函数,如果删除或新增了 yield 相关语句就可能会导致一些不明显错误; 只能在 yield 语法支持地方进行异步调用,无法异步调用类似 with 或 for 这样语句,限制了可用性。...稍后会在提案中提及:新 async with 语句允许 Python 程序进入或退出上下文上执行异步调用,而新 async for 语句可以迭代器中执行异步调用。...await 只能跟一个 可等待对象(awaitable),可以是以下选项之一: 原生函数返回原生对象; 被 types.coroutine() 装饰函数中返回生成式对象; 一个拥有...() 接收原生对象和原生方法需要返回 False。...为了使就成为与生成器不同原生概念: 如果未被 await 直接调用会抛出 RuntimeWarning 异常; 还建议 sys 模块中添加两个新函数:set_coroutine_wrapper

    11710
    领券