Javascript 承诺会阻塞堆栈吗 [英] Do Javascript promises block the stack

查看:21
本文介绍了Javascript 承诺会阻塞堆栈吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Javascript 承诺时,事件循环是否被阻塞?

When using Javascript promises, does the event loop get blocked?

我的理解是使用 await &异步,使堆栈停止,直到操作完成.它是通过阻塞堆栈来实现的,还是类似于回调并将进程传递给某种 API 来实现的?

My understanding is that using await & async, makes the stack stop until the operation has completed. Does it do this by blocking the stack or does it act similar to a callback and pass of the process to an API of sorts?

推荐答案

使用 Javascript 承诺时,事件循环是否被阻塞?

When using Javascript promises, does the event loop get blocked?

没有.Promise 只是一个事件通知系统.它们本身不是手术.他们只是通过调用适当的 .then().catch() 处理程序来响应被解析或拒绝,如果链接到其他承诺,他们可以延迟调用这些处理程序,直到他们被链接起来的承诺也解决/拒绝.因此,单个 promise 不会阻塞任何内容,当然也不会阻塞事件循环.

No. Promises are only an event notification system. They aren't an operation themselves. They simply respond to being resolved or rejected by calling the appropriate .then() or .catch() handlers and if chained to other promises, they can delay calling those handlers until the promises they are chained to also resolve/reject. As such a single promise doesn't block anything and certainly does not block the event loop.

我的理解是使用 await &异步,使堆栈停止直到操作完成.它是通过阻止堆栈还是它的行为类似于回调并将过程传递给某种 API?

My understanding is that using await & async, makes the stack stop until the operation has completed. Does it do this by blocking the stack or does it act similar to a callback and pass of the process to an API of sorts?

await 只是一种语法糖,它用更简单的语法替换了 .then() 处理程序.但是,在幕后操作是相同的.await 之后的代码基本上放在一个不可见的 .then() 处理程序中,并且事件循环没有阻塞,就像没有阻塞一样.then() 处理程序.

await is simply syntactic sugar that replaces a .then() handler with a bit simpler syntax. But, under the covers the operation is the same. The code that comes after the await is basically put inside an invisible .then() handler and there is no blocking of the event loop, just like there is no blocking with a .then() handler.

注意解决以下评论之一:

Note to address one of the comments below:

现在,如果您要构建的代码通过不断解决的承诺来压倒事件循环(在某些评论中提出的某种无限循环中),那么事件循环将一遍又一遍地处理那些不断解决的承诺来自微任务队列,永远不会有机会处理在事件循环中等待的宏任务(其他类型的事件).事件循环仍在运行并且仍在处理微任务,但是如果您不断将新的微任务(已解决的承诺)塞入其中,那么它可能永远不会到达宏任务.关于是否将其称为阻塞事件循环"似乎存在一些争论.或不.这只是一个术语问题——更重要的是实际发生了什么.在这个无限循环的例子中,一遍又一遍地不断解决一个新的承诺,事件循环将继续处理那些已解决的承诺,而事件队列中的其他事件将不会得到处理,因为它们永远不会到达行的前面来获得它们的转动.这通常被称为饥饿".不是阻塞",但关键是如果您不断地无限地将新的微任务放入队列中,则宏任务可能无法得到服务.

Now, if you were to construct code that overwhelms the event loop with continually resolving promises (in some sort of infinite loop as proposed in some comments here), then the event loop will just over and over process those continually resolved promises from the microtask queue and will never get a chance to process macrotasks waiting in the event loop (other types of events). The event loop is still running and is still processing microtasks, but if you are stuffing new microtasks (resolved promises) into it continually, then it may never get to the macrotasks. There seems to be some debate about whether one would call this "blocking the event loop" or not. That's just a terminology question - what's more important is what is actually happening. In this example of an infinite loop continually resolving a new promise over and over, the event loop will continue processing those resolved promises and the other events in the event queue will not get processed because they never get to the front of the line to get their turn. This is more often referred to as "starvation" than it is "blocking", but the point is that macrotasks may not get serviced if you are continually and infinitely putting new microtasks in the queue.

在 Javascript 中应该避免这种无限循环不断解析新承诺的概念.它可能会使其他事件无法获得服务.

This notion of an infinite loop continually resolving a new promise should be avoided in Javascript. It can starve other events from getting a chance to be serviced.

这篇关于Javascript 承诺会阻塞堆栈吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆