首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >90%的人搞混同步异步,一个外卖订单就讲透了

90%的人搞混同步异步,一个外卖订单就讲透了

作者头像
用户1493530
发布2026-05-06 21:43:39
发布2026-05-06 21:43:39
110
举报

编程里的「同步」和「异步」,一个外卖订单就能讲明白

我写 iOS 写了快十年,最近一年基本上大部分代码都是 AI 帮我写的。前两天用 Claude Code 重构一个网络请求模块,它给我生成了一段异步代码,跑起来倒是没问题,但我顺手问了句"为什么这里用 async 而不是同步调用",它给我解释了一大段。我突然想到,这个概念我当年自学编程的时候也卡了好久。其实吧,同步异步真没那么玄乎,问题出在中文翻译上。很多人第一次看到「同步」这个词,脑子里浮现的是"同步进行""同步推进",觉得同步应该是好几件事一起干。但编程里恰恰相反,同步(Synchronous)的意思是"按顺序,一件一件来"

这锅得让翻译来背。Synchronous 这个词源自希腊语,syn 是"一起",chronos 是"时间",合在一起的本意是"在同一时间节奏上"。放到编程语境里,它描述的是调用方和被调用方在同一个时间线上锁步前进,你不走完我不动。而 asynchronous 加了个否定前缀 a-,就是"不在同一时间节奏上",你干你的我干我的,互不卡着。

说白了,同步 = 我等你做完再继续,异步 = 我先忙别的,你做完了通知我

就这一句话的事儿。但光说定义没用,得放到场景里才能理解透。

举个最夸张的例子。一个孕妇怀孕了,这是一个同步操作,需要十个月才能把孩子生出来。她想再生一个?对不起,你得等这个先生完,才能怀下一个。九个孕妇能不能一个月生出一个孩子来?不能。这就是同步的本质,有些操作天然不可并行,你只能老老实实排队等

但老板往往不这么想。在老板的世界观里,所有操作都是可并行的。一个孕妇十个月生一个小孩,老板会说:那我给你安排十个孕妇,一个月给我生出来行不行?这其实就是软件工程里经典的 《人月神话》 里的核心论点:往一个已经延期的项目里加人,只会让它更延期。 因为有些任务天然是串行的,你堆再多资源也没用,十个程序员也不能把一个需要十个月的需求压缩到一个月交付。CPU 再多核,一个 await 后面的代码也得等前面的 Promise resolve 了才能跑。

但异步的部分是什么呢?这个孕妇怀上之后,她不会原地罚站十个月等孩子蹦出来吧。她该上班上班,该追剧追剧,该跟闺蜜逛街逛街。肚子里的娃在后台默默"处理"着,到了日子阵痛一来,相当于操作系统给她推了一条中断通知:你的异步任务已完成,请接收结果。 于是她去医院,完成"回调"。

说白了,怀孕这件事本身是同步的(没法加速到一个月),但孕妇这个人是异步的(等待期间没有被阻塞)

一个外卖订单,把同步异步全讲明白

你中午饿了,有两种吃饭方式。

第一种:下楼去餐厅吃。 你走到餐厅,坐下来,点了一碗面,然后就坐在那儿等。厨师炒菜、下面、装盘,你全程干等着。面端上来之前,你啥也干不了。这就是同步调用。你的"主线程"(你这个人)被这碗面阻塞了。

第二种:打开外卖 App 点餐。 你下了一单黄焖鸡,手机显示"商家已接单"。然后呢?你不会站在门口傻等吧。你该追剧追剧,该打游戏打游戏,该哄孩子哄孩子。骑手取了餐、到了你楼下,App 给你推一条通知。你下楼取餐,吃饭。这就是异步调用。你的"主线程"(你这个人)在等餐的过程中完全自由。

这个比喻能映射出异步机制的每一个环节。你下单 = 发起异步请求。商家厨房 = 后台处理。骑手 = I/O 通道。App 推送通知 = 回调(Callback)。你的手机 = 事件循环,负责接收所有通知并告诉你该干嘛了。

再把这个场景往深了推一步。你不仅点了黄焖鸡,还同时在另一个平台下了一杯奶茶。两个订单各自独立处理,骑手各走各的路线,谁先到你先取谁的。这就是并发(Concurrency),一个人同时管好几件等待中的事。如果你叫上室友一起点,你俩各自下单各自取餐,那就是并行(Parallelism),多个人真的在同时干活。

下面这张时序图更完整地展示外卖场景中各个角色的交互过程:

四个容易搞混的概念,一次理清

写到这里,很多人会问:同步异步我大概懂了,但还有个"阻塞""非阻塞"是怎么回事?这两对概念经常被混在一起讲,CSDN 上超过一半的文章直接把"同步=阻塞、异步=非阻塞"画等号。其实吧,它们是两个不同的维度,可以交叉组合。

同步/异步描述的是消息通信机制:结果是你主动去拿的(同步),还是对方做完了通知你的(异步)。阻塞/非阻塞描述的是等待期间你的状态:你是干站着啥也不能干(阻塞),还是能干别的事儿(非阻塞)。

有一个经典的烧水壶比喻,四种组合对应四种场景:同步阻塞就是你用老式水壶烧水,站在旁边盯着,水没开之前哪儿也去不了。同步非阻塞就是你还是用老式水壶,但你时不时过来看一眼水开了没,中间去客厅坐会儿。异步阻塞就是你买了个会响的电水壶,但你还是非要站旁边等它响,虽然壶会通知你但你自己不肯走开。异步非阻塞就是电水壶烧着,你去看电视了,水开了壶自己会响。

实际开发中最常见的是两个极端:同步阻塞(最简单,代码直来直去)和异步非阻塞(性能最好,但代码复杂度高)。中间那两种很少刻意使用。

三个初学者最容易踩的坑

第一个坑:以为异步就是多线程。 这是排名第一的误解。JavaScript 是完全单线程的,但它从诞生之日起就在做异步操作。它靠的是事件循环(Event Loop),一个线程在多个任务之间快速切换。微软官方文档明确写过:async 和 await 关键字不会创建额外的线程。Baeldung 总结得最精练:多线程关注的是 workers(工人),异步关注的是 tasks(任务)。一个厨师在三道菜之间来回切换是异步,三个厨师各做一道菜是多线程。

第二个坑:以为异步一定更快。 把一个同步操作改成异步,那个操作本身不会变快,反而多了状态管理的开销。异步提升的是吞吐量,在一个操作等待 I/O 的时候,线程可以去服务其他请求。Stackify 有篇文章讲得很清楚:对 CPU 密集型任务(比如图像渲染、大量数学计算),异步完全没用,因为 CPU 全程在忙,根本没有"等待时间"可以利用。异步只在 I/O 密集(网络请求、数据库查询、文件读写)加上高并发的场景下才真正发光。

第三个坑:混淆并发和并行。 Go 语言之父 Rob Pike 有句经典的话:并发是同时处理很多事情,并行是同时很多事情。并发是一种程序设计能力,一个 CPU 核心通过切换也能并发。并行是物理执行层面的事,需要多核硬件。Node.js 是并发的(同时管着成千上万个连接),但运行在单线程上(没有并行)。

从回调地狱到 async/await:一部简史

理解概念是第一步,但编程里的异步之所以让人头疼,根源不在概念本身,而在于"异步的结果怎么传回来"这件事上。这个问题的解法经历了三代演进。

第一代是回调(Callback)。说白了就是你把一个函数当参数传进去,等异步操作完了调用它。问题是当你有好几个异步操作需要串起来的时候,一层套一层,代码往右缩进得越来越深,像个金字塔。这就是臭名昭著的"回调地狱"(Callback Hell)。

第二代是 Promise(ES2015)。它把嵌套拍平成了链式调用,.then().then().then(),错误处理也可以用 .catch() 统一兜底。代码好看多了,但长链条读起来还是费劲。

第三代是 async/await(JavaScript 在 ES2017 标准化)。它是 Promise 的语法糖,让异步代码看起来和同步代码几乎一模一样,还能用标准的 try/catch 处理错误。这个语法最早出现在 F# 2.0(2007 年),后来 C# 5.0(2012 年) 跟进,再到 Python 3.5(2015 年)、JavaScript(2017 年)、Rust(2019 年)、Swift 5.5(2021 年),从一门语言的实验特性变成了整个行业的标配,跨越了整整 10 年

拿我自己的 iOS 开发来说。以前用 GCD(Grand Central Dispatch) 写异步代码,核心操作就是 DispatchQueue.global().async 把耗时任务扔到后台队列,完成后再 DispatchQueue.main.async 切回主线程更新 UI。代码不复杂,但嵌套一多就眼花。Swift 5.5 引入原生 async/await 之后,同样的逻辑写出来清爽了一个量级。

不同语言处理异步的方式各有特点,下面这张思维导图做了一个快速梳理:

AI 时代,为什么你反而更需要搞懂这个

你可能会想:现在 AI 都能帮我写代码了,我还需要理解同步异步吗?

倒是恰恰相反。CodeRabbit 在 2025 年底发布的一份报告分析了 470 个 GitHub PR,发现 AI 生成的代码中并发相关的正确性问题是人类代码的大约 2 倍。常见的翻车场景包括:在 async 函数里混入同步阻塞调用、把本来故意写成同步的代码"优化"成异步、以及只在生产负载下才暴露的竞态条件。

更有意思的是 Anthropic 在 2026 年 1 月发的一项随机对照实验。他们让 52 名软件工程师分成两组学习 Python 的 Trio 异步库(一种结构化并发框架),一组用 AI 辅助,一组纯手写。结果 AI 辅助组的掌握度得分比手写组低了 17%,差距最大的地方是调试题。说白了,AI 帮你写出了能跑的异步代码,但你对"它为什么这么写""哪里可能出错"的判断力变弱了。

这跟我自己的体感也对得上。我用 Claude Code 写异步代码的时候,它生成得又快又好看,但偶尔会犯一些很隐蔽的错误,比如把两个可以并行的独立网络请求写成了顺序 await,白白浪费时间。如果我自己不理解异步的本质,这种问题我根本看不出来。

JetBrains 2025 年的 Python 开发者报告也明确提到:理解 async 和 await 将变得越来越重要。结构化并发正在成为下一代异步编程的核心范式,Java、Kotlin、Swift 都在往这个方向走。这些东西 AI 可以帮你写,但判断写得对不对,还是得靠你自己。

一句话带走

同步是你亲自去餐厅等面,异步是你点了外卖去追剧。 概念本身就这么简单。真正的挑战从来不是"什么是异步",而是"异步的结果怎么安全地传回来"。从 1976 年 Future 概念的诞生到 2025 年结构化并发的推广,整个行业花了将近 50 年才把这件事做到让普通开发者用起来不太痛苦。而在 AI 写代码的时代,能看懂这 50 年演进背后的逻辑,就是你和"只会让 AI 帮忙"的人之间的分水岭。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿族技术生活杂谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 编程里的「同步」和「异步」,一个外卖订单就能讲明白
    • 一个外卖订单,把同步异步全讲明白
    • 四个容易搞混的概念,一次理清
    • 三个初学者最容易踩的坑
    • 从回调地狱到 async/await:一部简史
    • AI 时代,为什么你反而更需要搞懂这个
    • 一句话带走
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档