# 异步操作(Asynchronous Operation)

想象一下,你去咖啡店点了一杯咖啡。如果这是一个同步操作,你会站在那里等待咖啡做好,期间你不能做其他事情,直到咖啡递到你手中。但如果是一个异步操作,你点完咖啡后可以找个地方坐下、看书或玩手机,等咖啡做好了,店员会叫你。这样,你不用一直等待,可以利用这段时间做其他事情。

在计算机编程中,异步操作的概念类似。程序在请求某个需要时间的操作(如读取文件、下载数据或加载场景)时,不会停下来等待操作完成,而是继续执行其他任务。当那个操作完成时,它会得到通知。

# 回调(Callback)

还是上面的咖啡店例子,当你的咖啡做好了,店员会叫你。这个 “叫你” 的动作,就是一个回调。它是咖啡店告诉你:“嘿,你的咖啡好了!”

在编程中,回调是一个函数或方法,它会在某个任务完成后被自动调用。当你启动一个异步操作时,你可以提供一个回调函数,这样当操作完成(或出现错误)时,这个函数就会被执行。

例如,你可能会告诉程序:“去加载这个场景,加载完成后,请执行这个回调函数来告诉我。” 当场景加载完成,你的回调函数就会被自动调用,你可以在其中执行一些后续操作,如显示一个 “加载完成” 的提示。

总结一下:

  • 异步操作就像是你在等待咖啡时可以做其他事情,而不是站在那里等。
  • 回调就像是咖啡做好后店员叫你的动作,告诉你任务已经完成了。

回调函数(Callback Function)是一种在某个操作(通常是异步操作)完成后被自动执行的函数。它的主要目的是允许程序知道某个任务已经完成,并允许程序在任务完成后执行特定的操作或处理。
在异步编程中,由于我们不知道操作何时完成,回调函数提供了一种机制来响应这些完成的操作。当异步操作完成时,回调函数被调用,通常带有操作的结果或任何相关的错误信息。

例如,当你从网络下载一个文件时,你可能会提供一个回调函数来处理下载完成后的操作,如保存文件、更新用户界面或处理任何下载过程中的错误。

简而言之,回调函数就像是一个 “通知” 或 “警报”,告诉程序:“嘿,你之前启动的那个操作已经完成了,现在你可以做一些后续的事情了!”

# 协程

# 协程(Coroutine)

协程是一种编程构造,它扩展了常规的子程序(或函数)的概念。与子程序不同,协程允许多个入口点和暂停及后续恢复执行的能力。

协程的关键特点是它可以在任何给定的点暂停执行(通常称为 “挂起”),并在稍后的某个时刻从暂停的地方恢复执行。这使得协程非常适合用于异步编程,因为它们可以在等待某些资源(如 I/O 操作、网络请求等)时挂起,而不会阻塞整个程序或线程。

# 协程与异步

协程本身不是异步的,但它们经常被用于异步编程。协程提供了一种更直观、更简洁的方式来处理异步操作,特别是在需要多个异步步骤的情况下。

例如,在 Python 中, asyncio 库使用 asyncawait 关键字提供了协程支持,使得异步编程变得更加简单和直观。

# 结论

协程本身不等同于异步,但它们为异步编程提供了强大的工具。通过使用协程,开发者可以更容易地编写异步代码,而不必深入了解回调、Promise 或其他复杂的异步模式。

# 协程 & 多线程

# 协程(Coroutine)

  1. 轻量级:协程是程序中的构造,不依赖于操作系统的线程。因此,创建和切换协程的开销通常比线程小得多。
  2. 协作式多任务:协程是协作式的,意味着在任何给定时间只有一个协程在执行。一个协程必须显式地让出控制权,以便其他协程可以运行。
  3. 没有并行性:由于协程是在单个线程上运行的,它们不会真正并行执行。但它们可以用于异步操作,如 I/O 操作,而不会阻塞主线程。
  4. 控制流:协程可以保存其执行状态(例如局部变量的值),这意味着它们可以在稍后的某个时刻从暂停的地方恢复执行。

# 多线程(Multithreading)

  1. 重量级:线程是操作系统级别的实体,因此创建、同步和切换线程的开销通常比协程大。
  2. 抢占式多任务:线程是抢占式的,这意味着操作系统可以在任何时候中断一个线程并开始执行另一个线程。
  3. 真正的并行性:在多核处理器上,多个线程可以真正并行执行。
  4. 同步问题:由于线程可以并行执行,它们可能会访问和修改共享资源,这可能导致竞态条件和其他同步问题。因此,线程间的同步和通信通常比协程更复杂。

# 总结

  • 协程是轻量级的、协作式的并发构造,适合于 I/O 密集型任务和需要高效上下文切换的场景。
  • 多线程是重量级的、抢占式的并发构造,适合于 CPU 密集型任务和需要真正并行执行的场景。