主流的js
环境都是单线程吗模式执行js 代码, js
采用为单线程的原因与最开始设计初衷有关,最早是运行在浏览器端的脚本语言,目的是为了实现页面上的动态交互,实现页面交互的核心就是dom
操作,这也就决定了js
必须使用单线程的模式来处理,不然就会造成严重的线程同步问题。如果js
多个线程同时修改dom
元素,此时浏览器就无法明确以那个线程的结果为准,为了避免这种线程同步问题,所以从一开始js就被设置成了单线程模式工作。这里所说的单线程指的是javascript执行环境中负责执行代码的线程只有一个
。
可以想象成只有一个人来执行任务,一个人一次只能执行一个任务,如果有多个任务就需要排队依次去完成。这种模式最大的优点是更安全更简单,缺点也很明显,遇到某一个特别耗时的任务后面的任务就需要等这个任务的结束,这也就导致整个程序的执行的拖延,出现假死的情况。
为了结局耗时任务的问题,javscript
把 任务的执行分了两种模式,分别是
Synchoronous
)Asynchronous
)Synchoronous
代码依次执行,后一个任务要等待前一个任务执行完成,同步执行比较简单,代码的执行顺序就是代码的顺序。单线程大部分都是同步模式。
Console
是输出的打印,Call stack
是执行栈
开始执行 js 会把我们的整体的代码加载进来并放到一个匿名函数里面执行,然后逐行开始执行,
第一行 执行会把 console.log('global begin')
压入调用栈中,控制台打印global begin
执行结束,弹出调用栈
接下来是两个函数的声明,函数的声明不会产生调用所以接着往下执行
接下来是一个foo
函数的调用,会把 foo
压入调用栈,foo
函数打印了一个消息,接着执行了 bar
函数,bar
函数也会被放入执行栈中,bar
函数执行过程中又打印了一次,bar
执行完毕弹出调用栈,紧接着 foo
函数也执行结束,弹出调用栈
最后打印了一个消息,也是一样的压栈,整体代码执行完,执行栈就会被清空掉
这种排队执行的机制下某行代码执行时间过长,后面的任务就会被延迟。我们把这种延迟称为阻塞,这种阻塞对于用户而言会有页面卡顿或者叫卡死,所以需要异步模式来解决程序中无法避免的耗时操作,比如ajax
操作,或者nodejs
中的大文件读写