JavaWeb 同步与异步深度解析 同步与异步区别

同步与异步因为 JavaScript 在同一时间只能处理一个任务,所有任务都需要排队,前一个任务执行完,才能执行下一个任务。如果前一个任务的执行时间很长,如执行AJAX操作或定时器操作时,后一个任务需要等它执行完毕才能向下执行,此时下面的任务就会被阻塞。

拿定时器来说,当用户向后台获取大量的数据时,就需要等到所有数据都获取完毕才能进行操作,用户只能在那里干等着,这种阻塞对用户来说意味着“卡死”,严重影响用户体验。在设计的时候,布莱登·艾奇就考虑到这个问题,将任务分为同步任务(synchronous)和异步任务(asynchronous)。

同步任务指的是,在主线程上排队执行的任务,只有前一个任务执行完毕,才会执行后一个任务。

异步任务指的是,不直接进入主线程执行,而是进入任务队列,只有等主线程任务执行完毕,任务队列开始通知主线程,请求执行任务,该任务才会进入主线程。

简单地说,同步任务执行之后,后面的任务必须等待同步任务得到计算结果并处理完成后才能执行;而异步任务在启动执行之后,后面的任务可以继续执行,当异步任务得到计算结果之后,会通知到主线程进行处理。

结合实际来说,如果在函数返回的时候,调用者还无法得到预期结果,而是要在将来通过一定的手段才能得到(如回调函数),这就是异步。例如,AJAX 操作。如果函数是异步的,发出调用之后,就会马上返回,但是不会马上返回预期结果。调用者不必主动等待,当被调用者得到结果之后,会通过回调函数主动通知调用者。

我们通过一个例子来描述同步和异步的区别,假如顾客去饭店吃饭,要点三道菜,分别是酸菜鱼、烤串和香菇炒油菜。若采用同步的方式进行处理,则顾客先向服务员点酸菜鱼,厨师先将酸菜鱼做好,然后吃完后再点烤串,烤串做好并吃完后再点香菇炒油菜,最后香菇炒油菜做好并吃完。整个过程中,不管上菜的时间有多久,都会等待上一道菜做好并吃完后,再点下一道菜,如图所示:



若采用异步的方式进行处理,则顾客同时向服务员点酸菜鱼、烤串、香菇炒油菜,哪道菜做好就先上哪道菜。这样一来,即使后厨在制作其中一道菜时浪费了时间,也并不会影响另外两道菜的烹饪,如图所示。做好哪道菜就上哪道菜,例如,上菜顺序如图12-7所示。

从前面的描述中可以得出结论:异步可以充分发挥计算机性能,使其不会因为执行一个耗时的任务导致后续代码被阻塞。可以想象,如果网页中需要获取一个网络资源,通过同步的方式获取,那么JavaScript需要等待资源完全从服务器端获取之后才能继续执行。这期间UI渲染也将停顿,这样的用户体验是非常不好的。而采用异步的方式获取,在下载网络资源期间,JavaScript和UI渲染都不会处于等待状态。

在JavaScript中,定时器、DOM事件和AJAX等的执行方式都是异步的。需要注意的是,异步方式执行的 JavaScript 代码仍然是单线程运行的。当异步任务计算完成,得到结果并通知主线程之后,也需要等待其他任务完成,主线程空闲时才能进行相关处理。对比同步和异步可知,同步操作通常是串行的,多个操作按顺序执行,前面的操作没有完成,后面的操作就必须等待。

而对于异步操作来说,多个操作相继开始并发执行,即使开始的先后顺序不同,但是由于它们各自是在自己独立的进程或线程中完成的,所以互不干扰,谁也不用等谁,如图12-9所示。

在实际应用中,AJAX 指的是不刷新浏览器窗口、不做页面跳转、局部更新页面内容的技术。真正的前后端分离是前端项目和后端项目分服务器端部署,在这里可以先理解为彻底舍弃服务器端渲染,数据全部通过AJAX方式以JSON格式来传递。

下一节我们会对AJAX应用展开详细介绍。

原文链接:,转发请注明来源!