订购诺言/异步/等待(面试问题)
问题:
new Promise((resolve) => {
console.log(1)
resolve()
}).then(async () => {
console.log(2)
}).then(async () => {
console.log(3)
})
new Promise((resolve) => {
console.log('a')
resolve()
}).then(() => {
console.log('b')
}).then(() => {
console.log('c')
}).then(() => {
console.log('d')
}).then(() => {
console.log('e')
})
答案:
1 一个 2 b c d 3 e,
但我认为答案是.... 1 A 2 B 3 CDE
请帮助分享如何思考以获取详细答案。谢谢。
Question:
new Promise((resolve) => {
console.log(1)
resolve()
}).then(async () => {
console.log(2)
}).then(async () => {
console.log(3)
})
new Promise((resolve) => {
console.log('a')
resolve()
}).then(() => {
console.log('b')
}).then(() => {
console.log('c')
}).then(() => {
console.log('d')
}).then(() => {
console.log('e')
})
Answer:
1
a
2
b
c
d
3
e
But I think answer is.... 1 a 2 b 3 c d e
Please help to share how to think to get answer detailed. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,我要解释说,没有人应该依靠两个单独的承诺链之间的精确时机。它们彼此独立运行,一旦您插入 任何现实世界中的任何同步操作 在任何一个承诺链中(所有现实世界的编程都将包含),,则每个链的时机与其他完全是不可预测的。
相反,真实代码中的时机取决于异步操作的时机,而不是其他任何内容。想象一下,这个承诺链中的每个步骤都在读取文件或进行一些随机延迟。这些是完全不可预测的操作,因此哪个链首先取决于实际异步操作的时机,而不是本示例中显示的内容。
因此,试图剖析每个项目何时进入承诺工作队列的详细信息,而何时进行维修是完全浪费编程时间,并且在任何实际编程问题中都不有用。
此外,如果您确实需要特定的操作订购,那么您不会使用两个独立的承诺链编程。取而代之的是,您使用承诺控制工具(例如将所有内容都链接到一个链中或使用
Promise.all()
,Promise.race.race()
等... )指导执行/完成订单准确地将其成为您想要的内容,而不管承诺实施的详细内部工作。然后,我将通过浏览诺言链之一的前两个链接来解释承诺队列如何工作的基础知识,只是表明我了解诺言是如何解决的,将其添加到承诺队列中,然后何时控制。即将返回事件循环,承诺队列中最古老的项目可以运行并调用其
.then()()
或 .catch()处理程序。这只是为了说明,您了解了预期的计划的基础知识,并且他们从自己的工作队列和事件循环中的大多数其他事项之前以Lifo顺序进行服务。然后,我要解释说,几年前,为了提高性能的兴趣而更改了规格,并在该规格更改之前或之后使用JS引擎可能会产生不同的结果。您不应该依靠该级别的实现细节的另一个原因。
如果面试官坚持我试图解释这个问题中的确切顺序,并且不听我的理由为什么这是毫无意义的练习,即使听到了我对我如何编码执行命令确实重要的现实情况的解释之后,然后,除非这只是一些真正的初级访调员试图变得聪明(并且要聪明自己),否则我必须得出结论,这不是一个好地方。没有高级开发人员必须坚持认为这是一种超级有价值或实用的练习,而不是表明您对承诺工作队列的工作原理有基本的了解。
First I would explain that nobody should ever rely on precise timing between two separate promise chains. They run independently of one another and as soon as you insert any real world asynchronous operations in either of those promise chains (which all real-world programming would contain), then the timing of each chain is entirely unpredictable vs. the other.
Instead the timing in real code depends upon the timing of the asynchronous operations, not on anything else. Imagine that each of the steps in this promise chain was reading a file or doing some random delay. Those are entirely unpredictable operations so which chain does what first depends upon the timing of the actual asynchronous operations, not on what is shown in this example.
So, trying to dissect the details of exactly when each item goes into the promise job queue and when it gets serviced is a complete waste of programming time and not useful in any real programming problem.
Further, if you really need a specific ordering of operations, then you don't program with two independent promise chains. Instead, you use promise flow-of-control tools (like chaining everything into one chain or using
Promise.all()
,Promise.race()
, etc...) to guide the execution/completion order into exactly what you want it to be regardless of the detailed inner workings of the promise implementation.Then, I would explain the basics of how the promise queue works by walking through the first two links of one of the promise chains just to show that I understand how a promise gets resolved, gets added to the promise queue and then, when control is about to return to the event loop, the oldest item in the promise queue gets to run and call its
.then()
or.catch()
handlers. This is just to illustrated that you understand the basics of how promises are scheduled and that they get serviced in LIFO order from their own job queue and before most other things in the event loop.Then, I would explain that a few years ago, the spec was changed for some promise steps in the interest of improving performance and a JS engine before or after that spec change would likely generate different results for something like then. Yet another reason why you shouldn't rely on that level of implementation detail.
If the interviewer insisted on me trying to explain the precise order in this problem and wouldn't listen to my reasoning why that's a pointless exercise, even after hearing my explanation for how I'd code a real world situation where execution order does matter, then unless this was just some really junior interviewer trying to be clever (and outsmarting themselves), I'd have to conclude this is not a good place to work. No senior developer should insist that this is a super valuable or practical exercise beyond showing that you have a basic understanding of how the promise job queue works.