Qter 发表于 2022-4-25 11:27:37

消息队列与ES6 作业队列


http://nodejs.cn/learn/the-nodejs-event-loop

消息队列当调用 setTimeout() 时,浏览器或 Node.js 会启动定时器。 当定时器到期时(在此示例中会立即到期,因为将超时值设为 0),则回调函数会被放入“消息队列”中。在消息队列中,用户触发的事件(如单击或键盘事件、或获取响应)也会在此排队,然后代码才有机会对其作出反应。 类似 onLoad 这样的 DOM 事件也如此。事件循环会赋予调用堆栈优先级,它首先处理在调用堆栈中找到的所有东西,一旦其中没有任何东西,便开始处理消息队列中的东西。我们不必等待诸如 setTimeout、fetch、或其他的函数来完成它们自身的工作,因为它们是由浏览器提供的,并且位于它们自身的线程中。 例如,如果将 setTimeout 的超时设置为 2 秒,但不必等待 2 秒,等待发生在其他地方。ES6 作业队列ECMAScript 2015 引入了作业队列的概念,Promise 使用了该队列(也在 ES6/ES2015 中引入)。 这种方式会尽快地执行异步函数的结果,而不是放在调用堆栈的末尾。在当前函数结束之前 resolve 的 Promise 会在当前函数之后被立即执行。有个游乐园中过山车的比喻很好:消息队列将你排在队列的后面(在所有其他人的后面),你不得不等待你的回合,而工作队列则是快速通道票,这样你就可以在完成上一次乘车后立即乘坐另一趟车。示例:JS
const bar = () => console.log('bar')

const baz = () => console.log('baz')

const foo = () => {
console.log('foo')
setTimeout(bar, 0)
new Promise((resolve, reject) =>
    resolve('应该在 baz 之后、bar 之前')
).then(resolve => console.log(resolve))
baz()
}

foo()

这会打印:TXT
foo
baz
应该在 baz 之后、bar 之前
bar

这是 Promise(以及基于 promise 构建的 async/await)与通过 setTimeout() 或其他平台 API 的普通的旧异步函数之间的巨大区别。
页: [1]
查看完整版本: 消息队列与ES6 作业队列