async/await和Synchronous的区别

async/await同步(Synchronous) 编程是两种处理任务的方式,核心区别在于 程序执行流是否会阻塞等待耗时操作完成。它们代表了不同的编程模型:

1. 同步(Synchronous)编程

  • 概念: 代码严格按照顺序一行一行执行。当遇到一个耗时操作(如读取大文件、网络请求、复杂计算)时,程序会停下来等待这个操作彻底完成,然后才继续执行后面的代码。

  • 特点:

    • 阻塞: 耗时操作会阻塞整个执行线程。在此期间,程序无法做其他任何事情(UI 会冻结、无法响应用户交互等)。
    • 简单直观: 代码流程是线性的,易于理解和调试(按顺序走就行)。
    • 适用场景: CPU 密集型计算、简单的脚本、不需要同时处理多个任务或保持 UI 响应性的情况。
  • 代码示例 (伪代码):

    javascript 复制代码
    function getData() {
      const data = readHugeFile(); // 程序停在这里等待文件读取完成
      processData(data);          // 文件读完后才能执行
      displayResults();           // 数据处理完后才能执行
    }

2. 异步(Asynchronous)编程(async/await 是其实现方式之一)

  • 概念: 遇到耗时操作时,程序不会停下来等待 。它会先启动这个操作,然后立即继续执行 后面的代码。当耗时操作在后台完成后(比如文件读好了、网络响应回来了),程序会通过某种机制(回调函数、Promise、事件)得到通知,并回过头来处理这个操作的结果

  • async/await 的作用: 它是基于 Promise 的语法糖,目的是让异步代码的书写和阅读看起来更像同步代码 ,极大地改善异步编程的可读性和可维护性,避免"回调地狱"。

    • async: 声明一个函数是异步函数。这个函数总是返回一个 Promise
    • await只能在 async 函数内部使用 。它放在一个 Promise 前面,作用是暂停当前 async 函数的执行等待这个 Promise 完成(resolve 或 reject) 。在等待期间,JavaScript 引擎可以去做其他工作(处理事件、执行其他脚本等) 。Promise 完成后,await 会提取 Promise 的结果值(resolve 的值)或抛出拒绝原因(reject 的值),然后恢复 async 函数的执行。
  • 特点:

    • 非阻塞: 耗时操作启动后,主线程可以立即继续执行其他任务,保持 UI 响应性和程序效率。
    • 高效: 充分利用单线程资源,避免因等待 I/O 而浪费 CPU 时间,能同时处理多个请求或任务。
    • 复杂性: 代码流程不再是简单的线性顺序,理解执行顺序需要了解事件循环(Event Loop)、回调队列等概念。async/await 显著降低了这种复杂性。
    • 核心机制: 依赖 JavaScript 的 Event LoopPromise 微任务队列。
  • 代码示例 (使用 async/await):

    javascript 复制代码
    async function getData() {
      try {
        const data = await fetchDataFromNetwork(); // (1) 启动请求,(2) 暂停函数执行,(3) 请求完成恢复执行并赋值给data
        const processed = await processDataAsync(data); // 等待处理完成
        displayResults(processed);
      } catch (error) {
        handleError(error); // 用try/catch捕获await Promise的reject
      }
    }

核心区别总结表

特性 同步 (Synchronous) 异步 (Asynchronous) / async/await
执行流 顺序执行,遇到耗时操作阻塞等待 启动耗时操作后立即继续 执行后续代码,操作完成后回调/恢复处理结果
阻塞性 阻塞主线程 非阻塞主线程
性能影响 可能导致 UI 冻结、整体吞吐量低 保持 UI 响应、高吞吐量(能处理更多并发)
代码风格 线性、简单直观 传统回调:嵌套复杂(回调地狱)。async/await类似同步的线性写法
错误处理 通常使用 try/catch 回调:需单独处理错误。Promise:.catch()async/await可用 try/catch
返回值 直接返回操作结果 回调:无直接返回值。Promise:返回 Promise 对象。async函数:返回 Promise
等待机制 无,直接等待完成 await暂停当前 async 函数的执行,等待 Promise 完成
适用场景 简单任务、CPU 密集型计算 I/O 操作(文件、网络)、需要高响应性(UI、服务器)

关键点强调

  1. await 只在 async 函数内暂停: await 暂停的是它所在的 async 函数的执行不是阻塞整个 JavaScript 线程!在等待期间,JavaScript 引擎可以执行其他代码(如事件处理、其他脚本)。这正是非阻塞的关键。
  2. async 函数总是返回 Promise: 即使函数体里没有 await,或者 return 一个普通值,该函数返回的也是一个立即 resolve 的 Promise。
  3. async/await 基于 Promise: async/await 是使用 Promise 的更优雅方式。await 后面通常跟一个 Promise(虽然跟非 Promise 值也能工作,但会自动包装成 resolved Promise)。
  4. 错误处理更友好: async/await 允许使用熟悉的 try/catch 块来处理异步操作中的错误,这是相比传统回调或仅用 Promise 链(.then().catch())的一大优势。

简单比喻

  • 同步: 你去餐厅点餐,站在柜台前一直等到 厨师做好你的菜,端给你,你才离开去吃饭。期间你不能做其他事(排队的人也被你堵住了)。
  • 异步(传统回调): 你点餐,拿到一个号码牌。你可以离开柜台去做别的事 (玩手机)。厨师做好菜会喊你的号码(回调),你听到后再去取。
  • 异步(async/await): 你点餐,服务员告诉你"请稍坐,我等下把菜送来 "(类似返回 Promise)。你可以坐下看手机(执行其他代码) 。当菜准备好时,服务员自动送到你面前(await 完成,恢复执行),你开始吃。整个过程感觉像同步等待服务员送餐,但实际你等待时是自由的。

总结: async/await 是让你以同步代码的书写风格 ,写出非阻塞的异步代码的强大工具。它解决了异步编程中回调嵌套带来的复杂性问题,同时保持了异步非阻塞的高效特性。理解其背后的 Promise 和 Event Loop 机制对于深入掌握它至关重要。

相关推荐
LjQ204020 分钟前
Java的一课一得
java·开发语言·后端·web
求知摆渡1 小时前
共享代码不是共享风险——公共库解耦的三种进化路径
java·后端·架构
brzhang2 小时前
前端死在了 Python 朋友的嘴里?他用 Python 写了个交互式数据看板,着实秀了我一把,没碰一行 JavaScript
前端·后端·架构
该用户已不存在2 小时前
不知道这些工具,难怪的你的Python开发那么慢丨Python 开发必备的6大工具
前端·后端·python
Xy9102 小时前
开发者视角:App Trace 一键拉起(Deep Linking)技术详解
java·前端·后端
嘻嘻哈哈开森2 小时前
技术分享:深入了解 PlantUML
后端·面试·架构
vvw&2 小时前
Linux 中的 .bashrc 是什么?配置详解
linux·运维·服务器·chrome·后端·ubuntu·centos
厚道2 小时前
Elasticsearch 的存储原理
后端·elasticsearch
不甘打工的程序猿2 小时前
nacos-client模块学习《心跳维持》
后端·架构