Day 05 JavaScript 同步(Sync) vs 非同步(Async)处理

笔者一开始看到这两个词的时候充满着黑人问号???
同步不是应该表示可以同时处理多件事,
而非同步不是应该表示一次只能处理一件事吗?
怎麽实际上跟我原本的理解完全相反!!!

同步 Synchronous

在 JS 的世界里,JS 的本质为 Sync,他的意思表示一次只能做一件事。
JS 使用的资料结构为 stack 堆叠(後进後出),需要等上层的事件做完才能做下层的事件。
https://ithelp.ithome.com.tw/upload/images/20210918/20139241K3NXCwHZrr.png
如果用函式让他一直循环,到最後记忆体会满出来,出现 Ranger Error,
称做 stack overflow,跟工程师圈里知名的查找问题的网站同名。
跟无穷回圈不太一样,无穷回圈只会卡住,不会喷错误讯息。

以下的范例是 JS 遇到无穷回圈的状况:
1.因为同步的关系,JS 由上而下一次只能做一件事,console.log('JS')会加到 stack 里,并马上拿出执行,印出 JS。
2.而执行到回圈时也会加到 stack 里,因为此范例是无穷回圈,所以会一直执行,造成卡住的状态。
3.卡住後无法添加 console.log('Ruby') 到 stack 里,没办法印出後面的 Ruby。

范例

console.log('JS');

for(let a = 1; a > 0; a++) {
  console.log("hi")
}

console.log('Ruby');

结果

JS
hi(一直执行)

非同步执行 Async

不会通通都卡在 Stack 区块,把 JS 自己该做的事做完再做浏览器的事。
非 JS 内建语法,如 Web API (注解[3]) 的 setTimeout callback 不会卡在 stack 区块里。
一开始会先在 stack 区块出现,接着瞬间丢给 Web API Runtime(执行环境) 执行,
等设定的时间过了之後来到 Queue 排队区(会按照顺序排列),
最後等 stack 区块里的程序码跑完,setTimeout callback 才会跑到 stack 区块执行结果。
详细流程解说可参考注解[4]。

以下的范例是 JS 遇到 Web API 的 setTimeout 的状况:
1.JS 会先印出来。
2.因为非同步的关系,setTimeout 函式会被丢到 Web API Runtime 执行。
3.Ruby 会被印出来。
4.过一秒後 Python 被印出。

范例

console.log('JS');

setTimeout(() => {
  console.log("Python")}
  , 1000);

console.log('Ruby');

结果

JS
Ruby
Python

或许你会想问如果我把 setTimeout 後面的时间改成 0 秒会不会改变结果。
答案是...不会
因为他是 Web API 的函式,一开始丢到 stack 後还是会被丢到 Web API Runtime 执行,
接着来到 Queue 排队区,最後回到 JS 被执行,
这是执行顺序的问题,不是时间的问题。

结论

  • JS 的同步处理:因为 JS 的资料结构是堆叠,所以一次只能处理一件事。
  • JS 的非同步处理:因为有 Web API 的帮忙,让有些属於 Web API 的函式可以先丢到 Web API 去执行,丢过去之後 JS 还是可以执行他的原生函式,等执行完後再处理刚刚丢到 Web API 的函式。

参考:
[1]MDN:非同步的 JavaScript 介绍
[2]Data Structure with JavaScript: Stacks
[3]MDN:Web APIs
[4]Loupe


<<:  30天打造品牌特色电商网站 Day.6 Figma实作第一个网站

>>:  Day 5: LeetCode 88. Merge Sorted Array

DAY8 Kotlin的第一步

学习这个语言第一个遇到的问题就是...... 要念Kotiln还是念Kotlin,思考许久发现, 一...

python3的环境安装

我使用的版本是python3.8.6,示范安装用的目前(20210721)最新的版本 首先到官网下载...

Day 11 - 除了写程序之外还要访谈厂商之体验

昨天的文章有提到计画案有部分的厂商是需要去挖掘的,也因此今天会来分享一个计画案出现前与厂商面谈的心得...

【第十九天 - Flutter Firebase Dynamic Links】

前言 今日想要介绍 Deep Link,这边我只有接收 deeplink 的连结实作,并没有使用动态...

InnoDB的表格空间-Part2(各类型页面详细情况)

今天来进一步探讨更细节的几个问题 像是XDES Entry结构到底储存在表格空间的那边? 直属於表格...