笔者一开始看到这两个词的时候充满着黑人问号???
同步不是应该表示可以同时处理多件事,
而非同步不是应该表示一次只能处理一件事吗?
怎麽实际上跟我原本的理解完全相反!!!
在 JS 的世界里,JS 的本质为 Sync,他的意思表示一次只能做一件事。
JS 使用的资料结构为 stack 堆叠(後进後出),需要等上层的事件做完才能做下层的事件。
如果用函式让他一直循环,到最後记忆体会满出来,出现 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(一直执行)
不会通通都卡在 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 被执行,
这是执行顺序的问题,不是时间的问题。
参考:
[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
学习这个语言第一个遇到的问题就是...... 要念Kotiln还是念Kotlin,思考许久发现, 一...
我使用的版本是python3.8.6,示范安装用的目前(20210721)最新的版本 首先到官网下载...
昨天的文章有提到计画案有部分的厂商是需要去挖掘的,也因此今天会来分享一个计画案出现前与厂商面谈的心得...
前言 今日想要介绍 Deep Link,这边我只有接收 deeplink 的连结实作,并没有使用动态...
今天来进一步探讨更细节的几个问题 像是XDES Entry结构到底储存在表格空间的那边? 直属於表格...