✨浏览器特性

js是一个单线程,非阻塞,异步脚本语言

在执行栈中先进后出  (相对与函数中调用函数,单行代码执行直接出去了)

栈里面表现很慢的东西叫阻塞 slow

//比如http请求

如果我们在浏览器控制台中运行'foo'函数,是否会导致堆栈溢出错误?

function foo() {
  setTimeout(foo, 0); // 是否存在堆栈溢出错误?
};

引言:

JavaScript并发模型基于“事件循环”。 当我们说“浏览器是 JS 的家”时我真正的意思是浏览器提供运行时环境来执行我们的JS代码

浏览器的主要组件包括 调用堆栈事件循环,任务队列Web API。 像 setTimeoutsetIntervalPromise这样的全局函数不是JavaScript的一部分,而是 Web API 的一部分。 JavaScript 环境的可视化形式如下所示:

 JS调用栈是后进先出(LIFO)的。引擎每次从堆栈中取出一个函数,然后从上到下依次运行代码。每当它遇到一些异步代码,如setTimeout,它就把它交给Web API(箭头1)。因此,每当事件被触发时,callback 都会被发送到任务队列(箭头2)。

事件循环(Event loop)不断地监视任务队列(Task Queue),并按它们排队的顺序一次处理一个回调。每当 调用堆栈(call stack)为空时, Event loop获取回调并将其放入 堆栈(stack )(箭头3)中进行处理。请记住,如果调用堆栈不是空的, 则事件循环不会将任何回调推入堆栈

步骤

  1. 调用 foo()会将foo函数放入调用堆栈(call stack)
  2. 在处理内部代码时,JS引擎遇到setTimeout
  3. 然后将foo回调函数传递给WebAPIs(箭头1)并从函数返回,调用堆栈再次为空
  4. 计时器被设置为0,因此foo将被发送到任务队列<Task Queue>(箭头2)。
  5. 由于调用堆栈是空的,事件循环将选择foo回调并将其推入调用堆栈进行处理。
  6. 进程再次重复,堆栈不会溢出。


猜你喜欢

转载自www.cnblogs.com/-constructor/p/12355526.html