node新手,求教一个观察者队列的问题
发布于 5 年前 作者 Mr-zhuxing 4578 次浏览 来自 问答

一个关于promise与setTimeout的程序

程序如下

var p = new Promise(function(resolve,reject){
    resolve()
})
p.then(function(value){
    console.log('promise_1')
}).then(function(value){
    console.log('promise_2')
})
setTimeout(() => {
    console.log("timeout_1");
    p.then(function(value){
        console.log('promise_3')
    }).then(function(value){
        console.log('promise_4')
    })
}, 0);
setTimeout(() => {
    console.log("timeout_2");
    setTimeout(() => {
        console.log('timeout_3')
    }, 0);
    p.then(function(value){
        console.log('promise_5')
    })
}, 0);
console.log('start');
for(let i=0;i<1000000000;i++){}

最终得到的结果是 start promise_1 promise_2 timeout_1 timeout_2 promise_3 promise_5 promise_4 timeout_3

所以是 在node中是先把promise的任务队列执行完后 在执行定时器观察者的任务队列

promise_4应该先加入到任务队列才对呀 可是为什么promise_5又在promise_4前执行

3 回复

因为promise.then 是 nextTick 的时候执行的,也就是插入到本轮事件轮询里面, setTimeout 是在下次事件轮询里面执行的. 3,4,5 是在同一个 事件轮询里面执行的 你的问题可以简化为

var p = new Promise(function(resolve,reject){
  resolve()
})
var p2 = new Promise(function(resolve,reject){
  resolve()
})
p.then(()=>{
  console.log('p promise 1')
}).then(()=>{
  console.log('p promise 2')
})
p2.then(()=>{
  console.log('p2 promise 1')
}).then(()=>{
  console.log('p2 promise 2')
})

因为执行完 promise 1 才会将 promise2 插入到事件轮询里. 所以结果是

p promise 1
p2 promise 1
p promise 2
p2 promise 2

@abiuDoIT 噢噢,请问那么关于setTimeout、 promise、 nextTick、setImmediate 、文件读写。这些事件。假设这些事件的回调函数都已经被交到队列里面,又该如何判别这些事件的轮询的优先级呢????

@abiuDoIT 我刚刚实验了一下,大概得出的结论是这样 事件观察者队列分为多个,比如promise的队列,nextTick的队列,setTimeout的队列,setImmediate的队列。

优先级是nextTick的队列>promise的队列>setTimeout的队列>setImmediate的队列

比如这四个队列,是四轮循环四轮循环的执行,但是遇到优先级比当前队列高的,就加到本轮循环末尾,。 比如当前正在执行setTimeout的队列,遇到promise,就把promise的回调加到本轮循环队列尾部

感觉还是有点懵逼

回到顶部