18 Apr 2017 08:54 +0000
当函数返回时,调用者能够拿到预期结果,则称该函数是 同步 (synchronous) 的,反之称该函数是 异步 (asynchronous) 的。就是说,在主线程内完成的任务是同步的,主线程外产生额外线程的任务是异步的。
下面这篇文章有一个很形象的比喻:
JavaScript:彻底理解同步、异步和事件循环(Event Loop)
同步:
线程 A (主线程): 接下来要处理一个 ajax 请求
线程 A: 发送请求 // 这时 A 被占用,不能进行其他任务
线程 A: ... // 等待返回
线程 A: 请求成功返回了,拿到返回的数据
线程 A: 继续执行其余代码.
实际上的 ajax 线程是异步的。
异步:
线程 A (主线程): B,这里有一个 ajax 请求,我把参数给你了,你去处理吧。
线程 B: OK // 返回
线程 A: ... // 尚未得到预期结果,继续执行其余代码
线程 B: ...
线程 A: ...
线程 B: 请求成功返回了.
线程 A: 好的 // 得到预期结果
异步和多线程的关系可以这么概括: 异步是目的,多线程是异步的一种手段。
可见,异步操作时,A 不能在调用函数返回时得到预期结果。但如果在 A 中需要用到调用函数的返回结果怎么办呢? JavaScript 中的解决方法有若干程,最常用的是同步回调:
线程 A (主线程): B,这里有一个 ajax 请求,我把参数和回调函数都给你了,你去处理吧。
线程 B: OK // 返回
线程 A: ... // 尚未得到预期结果,继续执行其余代码
线程 B: ...
线程 A: ...
线程 B: 请求成功返回了
/*
* 按照回调的定义,此时 A 会执行回调函数,不过,A 有可能正在执行
* 其他代码,因此 B 会将返回作为一个事件放入事件队列
*/
线程 A: 忙完手头的事情了.
线程 A: 我检查一下 B 有没有返回 // 检查事件队列的操作一直都在进行
线程 A: 检查到事件队列中有返回的事件,所以先响应这个事件 // 执行回调函数
消息队列是先进先出的。
REFERENCE
Loading comments...