JavaScript异步通信三种玩法实例代码

 更新时间:2025年12月11日 09:53:41   作者:张较瘦_  
在JavaScript中实现异步编程的方法多种多样,每种方法都有其特定的应用场景和优缺点,这篇文章主要介绍了JavaScript异步通信三种玩法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

JavaScript 异步通信实例

你有没有过这样的经历:去咖啡店点单,店员说"需要等5分钟"。如果站在柜台前一动不动地等(同步),这5分钟啥也干不了;但如果先去旁边买份报纸,等咖啡好了店员喊你(异步),这就高效多了。

JavaScript 里的"异步通信",本质上就是这种"不等结果先干活"的机制。

为什么 JavaScript 需要异步?

先搞懂一个前提:JavaScript 是单线程的。就像一个只有一个厨师的厨房,同一时间只能做一件事。

如果遇到"耗时操作"(比如从服务器拿数据、读文件),如果让线程一直等着(同步),整个程序就会"卡住"——页面点不动、按钮没反应,用户体验会烂到家。

所以,异步就是让 JavaScript 能在等结果的时候,先去处理其他任务的"小聪明"。

异步通信的三种玩法(从简单到高级)

咱们从最原始的方法开始,一步步升级,每个方法都配可执行的代码,你可以直接复制到浏览器控制台跑一跑。(注意,代码运行结果的顺序非常重要!)

1. 回调函数:最早的"留个联系方式"

回调函数是最基础的异步处理方式。就像点咖啡时告诉店员"做好了打我电话12345",这个"12345"就是回调函数。

示例1:用定时器模拟异步操作

// 模拟一个"煮咖啡"的异步操作(需要2秒)
function makeCoffee(callback) {
  console.log("开始煮咖啡...");
  // 2秒后执行回调函数(通知咖啡好了)
  setTimeout(() => {
    const coffee = "热拿铁";
    callback(coffee); // 调用回调,把结果传过去
  }, 2000);
}

// 点咖啡时,留个"回调联系方式"
makeCoffee((coffee) => {
  console.log(`咖啡好了:${coffee},开始喝!`);
});

// 注意:这行代码会先执行(不等咖啡煮好)
console.log("等咖啡的时候,先刷会儿手机...");

运行结果(顺序很重要):

开始煮咖啡...
等咖啡的时候,先刷会儿手机...
// 2秒后...
咖啡好了:热拿铁,开始喝!

问题:回调地狱

如果多个异步操作要按顺序执行(比如先煮咖啡,再烤面包,再煎蛋),回调会嵌套成"地狱":

// 回调地狱示例(别这么写!)
makeCoffee((coffee) => {
  console.log(`喝了${coffee}`);
  makeBread((bread) => {
    console.log(`吃了${bread}`);
    makeEgg((egg) => {
      console.log(`吃了${egg},早餐完成!`);
    });
  });
});

嵌套越多,代码越难维护,就像剥洋葱一样让人头疼。

2. Promise:给异步操作"立个军令状"

Promise 是 ES6 推出的解决方案,它像一个"军令状"——承诺"我会完成任务,结果要么成功要么失败"。用 .then() 处理成功,.catch() 处理失败,解决了回调地狱的嵌套问题。

示例2:用 Promise 改写煮咖啡

// 用 Promise 包装异步操作
function makeCoffee() {
  console.log("开始煮咖啡...");
  // 返回一个 Promise "军令状"
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true; // 模拟是否成功
      if (success) {
        resolve("热拿铁"); // 成功:兑现承诺
      } else {
        reject("咖啡机坏了!"); // 失败:拒绝承诺
      }
    }, 2000);
  });
}

// 用 .then() 接结果,.catch() 处理错误
makeCoffee()
  .then((coffee) => {
    console.log(`咖啡好了:${coffee},开始喝!`);
    // 可以继续返回新的 Promise,实现链式调用
    return "喝完咖啡,准备烤面包";
  })
  .then((msg) => {
    console.log(msg);
  })
  .catch((error) => {
    console.log("出错了:", error);
  });

console.log("等咖啡的时候,先刷会儿手机...");

运行结果和之前一样,但代码是"平着写"的,不是嵌套的!这就是 Promise 解决回调地狱的核心:链式调用

3. async/await:让异步代码看起来像同步

ES2017 推出的 async/await 是 Promise 的"语法糖",能让异步代码写起来和同步代码几乎一样,更符合人类的思维习惯。

示例3:用 async/await 简化代码

// 还是用上面的 makeCoffee(返回 Promise)
function makeCoffee() {
  console.log("开始煮咖啡...");
  return new Promise((resolve) => {
    setTimeout(() => resolve("热拿铁"), 2000);
  });
}

// 再加一个烤面包的异步函数
function makeBread() {
  console.log("开始烤面包...");
  return new Promise((resolve) => {
    setTimeout(() => resolve("全麦面包"), 1500);
  });
}

// 用 async 声明异步函数,内部可以用 await
async function makeBreakfast() {
  console.log("开始做早餐...");
  
  // 等咖啡做好(await 会"暂停"到 Promise 完成)
  const coffee = await makeCoffee();
  console.log(`咖啡好了:${coffee}`);
  
  // 再等面包烤好(按顺序执行,不嵌套)
  const bread = await makeBread();
  console.log(`面包好了:${bread}`);
  
  return "早餐完成!";
}

// 调用异步函数(返回 Promise)
makeBreakfast().then((result) => {
  console.log(result);
});

console.log("主线程:我先去干别的了...");

运行结果:

开始做早餐...
主线程:我先去干别的了...
开始煮咖啡...
// 2秒后...
咖啡好了:热拿铁
开始烤面包...
// 再1.5秒后...
面包好了:全麦面包
早餐完成!

是不是像同步代码一样直观?但注意:await 只能在 async 函数里用,而且它不会阻塞主线程(其他代码该跑还是跑)。

实战:用异步通信请求网络数据

实际开发中,最常见的异步通信就是"从服务器拿数据"。咱们用 fetch API(返回 Promise)来演示:

// 用 async/await 请求网络数据
async function queryGoodsData() {
  try {
  	  console.log("开始请求");
    // 1. 发请求(await 等响应)
    const response = await fetch("https://suggest.taobao.com/sug?code=utf-8&q=%E5%8D%AB%E8%A1%A3");
    const data = await response.json();
    // 2. 显示结果
    console.log("请求完成,结果数据:", data );

  } catch (error) {
    // 处理错误(比如网络问题)
    console.log("请求失败:", error);
  }
}

// 调用函数
queryGoodsData();
console.log("正在请求数据,稍等...");

先试用浏览器访问 https://suggest.taobao.com/sug(为了解决跨域问题),然后启用控制台,将上述代码直接复制到控制台,会看到先输出"正在请求数据",然后过一会儿显示获取到的商品信息。

总结:三种方式怎么选?

  • 回调函数:适合极简单的场景(比如单个定时器),但多步异步会变乱。
  • Promise:解决了回调地狱,支持链式调用,适合复杂异步流程。
  • async/await:Promise 的简化写法,代码最易读,优先推荐使用。

记住核心:异步通信就是让 JavaScript"不等结果先干活",避免程序卡住。就像生活中"多线程"处理任务一样,高效又不耽误事。

现在,你能不能用自己的话讲讲什么是异步通信了?如果能,说明你真的懂了~

到此这篇关于JavaScript异步通信三种玩法的文章就介绍到这了,更多相关JS异步通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mybatis-plus批量插入的2种方式总结

    Mybatis-plus批量插入的2种方式总结

    这篇文章主要给大家总结介绍了关于Mybatis-plus批量插入的2种方式,Mybatis-Plus提供了多种方式进行批量插入优化,文中通过代码示例将实现的方法介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • Java 输入多行字符串或者多个int数值的方法

    Java 输入多行字符串或者多个int数值的方法

    今天小编就为大家分享一篇Java 输入多行字符串或者多个int数值的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • 关于springboot的接口返回值统一标准格式

    关于springboot的接口返回值统一标准格式

    这篇文章主要介绍了关于springboot的接口返回值统一标准格式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Java数据类型Integer与int的区别详细解析

    Java数据类型Integer与int的区别详细解析

    这篇文章主要介绍了Java数据类型Integer与int的区别详细解析,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null,int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比,需要的朋友可以参考下
    2023-12-12
  • java 使用ConcurrentHashMap和计数器实现锁

    java 使用ConcurrentHashMap和计数器实现锁

    这篇文章主要介绍了java 使用ConcurrentHashMap和计数器实现锁的相关资料,需要的朋友可以参考下
    2017-05-05
  • Spring Scheduler定时任务实战指南(零基础入门任务调度)

    Spring Scheduler定时任务实战指南(零基础入门任务调度)

    本文介绍SpringScheduler在电商订单超时处理中的应用,涵盖启用定时任务、使用@Scheduled注解、cron表达式配置、线程池优化及异步执行等核心内容,本文给大家介绍Spring Scheduler定时任务实战指南,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • Java 中函数作为参数传递方法详解

    Java 中函数作为参数传递方法详解

    文章介绍了Java中函数式编程的概念,包括Lambda表达式、方法引用和函数式接口,通过这些特性,Java可以将函数作为参数传递,从而实现更灵活和简洁的代码,文章还列举了Java内置的函数式接口,并展示了它们在Stream API中的应用,感兴趣的朋友跟随小编一起看看吧
    2025-11-11
  • Java实现五子棋AI算法

    Java实现五子棋AI算法

    这篇文章主要为大家详细介绍了Java实现五子棋AI算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-03-03
  • JavaCV实现读取视频信息及自动截取封面图详解

    JavaCV实现读取视频信息及自动截取封面图详解

    javacv可以帮助我们在java中很方便的使用OpenCV以及FFmpeg相关的功能接口。本文将利用Javacv实现在视频网站中常见的读取视频信息和自动获取封面图的功能,感兴趣的可以了解一下
    2022-06-06
  • 基于Intellij Idea乱码的解决方法

    基于Intellij Idea乱码的解决方法

    下面小编就为大家分享一篇基于Intellij Idea乱码的解决方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-03-03

最新评论