嘿javascript停止让我循环

A Guide to Understanding What is Going On in the JavaScript Event Loop

理解JavaScript事件循环中正在发生什么的指南

JavaScript: A Single Threaded, Non-Blocking, Asynchronous, Concurrent Language. That makes perfect sense…right? Absolutely not! How is it single threaded, meaning there is only one thing happening at a time, but also non-blocking? Here is where an understanding of the event loop comes into play. JavaScript utilizes the event loop, Web API’s, and a few smart data structures, to give us the illusion of a multi threaded language. Let’s take a look at what exactly is going on!

JavaScript:单线程,非阻塞,异步,并发语言。 完全有道理...对吗? 绝对不! 单线程如何处理,这意味着一次只发生一件事,而且无阻塞? 这里是对事件循环的理解。 JavaScript利用事件循环,Web API和一些智能数据结构,给我们一种多线程语言的错觉。 让我们看看到底发生了什么!

What Makes Up the Event Loop…The JavaScript event loop is made of a couple different components, the Call Stack and the Callback Queue.

是什么构成事件循环… JavaScript事件循环由几个不同的组件组成,即调用堆栈和回调队列。

The Call StackThe call stack is responsible for keeping track of all the operations that need to be executed. It is a last in, first out queue. Whenever the function at the top of the stack finishes executing it is popped off the stack and the next operation in line is completed.

调用堆栈调用堆栈负责跟踪需要执行的所有操作。 这是后进先出队列。 每当堆栈顶部的函数完成执行时,就会从堆栈弹出该函数,然后完成下一个操作。

Image for post

What exactly is happening in the above example…1. hello() is called and pushed onto the stack2. ‘Hello World’ is logged to the console3. learning() is called and pushed onto the stack4. ‘Never Stop Learning’ is logged to the console5. learning() finishes executing and is popped off the stack6. conclusion() is called and pushed on the stack7. ‘The End’ is logged to the console8. conclusion() finishes executing and is popped off the stack9. hello() implicitly returns since it reaches the end of the function and is popped of the stack10. The call stack is clear!

上面的示例中到底发生了什么……1。 调用hello()并将其推送到stack2上。 “ Hello World”已登录到控制台3。 调用learning()并将其推送到stack4上。 “永不停止学习”已记录到控制台5。 learning()完成执行并从堆栈中弹出6。 结论()被调用并压入堆栈7。 “结束”将记录到控制台8。 结论()完成执行并从堆栈中弹出9。 hello()隐式返回,因为它到达函数的末尾并从堆栈中弹出。 调用堆栈很清楚!

Blocking the StackThe call stack can be blocked when slow running synchronous code, such as a synchronous network request, image processing, or an infinite loop, is pushed onto the stack. Since the operation must complete running and then be popped off the stack before the next operation can occur, this can lead to frozen web pages, button clicks that don’t register immediately, and an overall unpleasant user experience. This is where asynchronous callbacks come to the rescue, allowing us to run ‘slow code’, without blocking the call stack.

阻塞堆栈当运行缓慢的同步代码(例如同步网络请求,图像处理或无限循环)被压入堆栈时,可以阻止调用堆栈。 由于该操作必须完成运行,然后在下一次操作发生之前从堆栈中弹出,因此这可能会导致网页冻结,按钮单击无法立即注册以及整体上令人不快的用户体验。 这是抢救异步回调的地方,它使我们可以运行“慢速代码”,而不会阻塞调用堆栈。

Callback QueueThe callback queue has one simple job, check when the stack is clear, when it is push the first callback in the queue onto the stack. If the callback queue is empty, just sit there and look pretty. Let’s break down an instance when the callback queue will come into play.

回调队列回调队列有一个简单的工作,检查堆栈是否清空,何时将队列中的第一个回调推送到堆栈上。 如果回调队列为空,则坐在那里看起来很漂亮。 让我们分解一个当回调队列起作用时的实例。

Image for post
  1. console.log() is pushed onto the stack

    console.log()被压入堆栈
  2. ‘Now’ is logged to the console

    “现在”已记录到控制台
  3. console.log pops off the stack

    console.log从堆栈弹出
  4. setTimeout() is pushed onto the stack

    setTimeout()被压入堆栈

    * setTimeout is provided to us as a Web API by the browser, so when setTimeout is pushed onto the stack it fires off to the Web API to complete running.

    *浏览器将setTimeout作为Web API提供给我们,因此,将setTimeout推入堆栈时,它将触发Web API以完成运行。

  5. This clears the stack and allows the next console.log() to be pushed onto the stack

    这将清除堆栈,并允许将下一个console.log()推入堆栈
  6. ‘We Know’ is logged to the browser

    “我们知道”已记录到浏览器
  7. Our timer from setTimeout() has elapsed, so the callback is pushed onto the callback queue

    来自setTimeout()的计时器已经过去,因此回调被推送到回调队列中
  8. The callback queue looks and sees that the call stack is clear DRUMROLL enter the event loop. The callback is pushed onto the stack.

    回调队列看起来并看到调用堆栈是清除的DRUMROLL进入事件循环。 回调被推入堆栈。
  9. ‘All About the Event Loop! YAY!’ is logged to the console

    “关于事件循环的一切! 好极了!' 记录到控制台
  10. The callback pops off the stack

    回调弹出堆栈

When a call is made to a Web API provided to us by the browser, such as fetch, setTimeout, AJAX request, etc. A request is made to the Web API. It does not block the stack because it is being run in the browser not the JavaScript runtime. The stack is clear to do other things. The request completes(or doesn’t) and is sent back to the callback queue, where the eventual completion is determined by when the stack is clear.

当调用由浏览器提供给我们的Web API时,例如访存,setTimeout,AJAX请求等。将对Web API进行请求。 它不会阻塞堆栈,因为它是在浏览器而不是JavaScript运行时中运行的。 堆栈很明显可以做其他事情。 该请求完成(或未完成),并被发送回回调队列,在该队列中最终的完成情况取决于堆栈的清除时间。

And that is how JavaScript is a single threaded, non-blocking, asynchronous, concurrent language.

这就是JavaScript成为单线程,非阻塞,异步,并发语言的方式。

Recap…1. JavaScript is single threaded, but the use of Web API’s to handle things like fetch/AJAX network requests and setTimeout/SetInterval give us the illusion of a multi-threaded language.2. The callback queue handles these callbacks when they are returned from the Web API. Only when the call stack is clear will these callbacks be pushed onto the stack for completion. This allows us to have ‘slow code’ be non-blocking.

回顾…… 1. JavaScript是单线程的,但是使用Web API处理诸如fetch / AJAX网络请求和setTimeout / SetInterval之类的事情,给我们一种多线程语言的错觉。 从Web API返回时,回调队列将处理这些回调。 仅当清除调用堆栈时,这些回调才会被压入堆栈以完成操作。 这使我们可以使“慢速代码”成为非阻塞的。

Image for post
explanation by Phillip Roberts 解释

翻译自: https://medium.com/@kelly.lynn.becker/hey-javascript-stop-throwing-me-for-a-loop-2ece252a677d

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值