Прежде всего, что такое EventLoop?
Весь рабочий механизм js также называется Event Loop (цикл событий)
EventLoop разделен на два типа: боковая сторона браузера и сторона узла
Почувствуй код
setTimeout(() => {
console.log(1)
Promise.resolve(3).then(data => console.log(data))
}, 0)
setTimeout(() => {
console.log(2)
}, 0)
//浏览器 1 3 2
//node 1 2 3
Браузерный цикл событий
Во-первых, будет стек во время выполнения, а затем будет очередь событий и пространство микрозадач (названное вами)
Когда наш код выполняется синхронно сверху вниз, мы будем записывать время, когда мы столкнемся с setTimeout.Когда время истечет, мы поместим это событие в очередь событий.Когда мы столкнемся с микрозадачами, мы поместим микрозадачи в микрозадачу пробел, и код будет продолжаться. Выполнять до тех пор, пока синхронный код не будет выполнен.
После завершения мы увидим, есть ли какие-либо микрозадачи в пространстве микрозадач, если да, мы выполним все микрозадачи в пространстве микрозадач, а затем перейдем в очередь, чтобы получить наши события для выполнения.Если есть микрозадачи во время выполнения , они будут по-прежнему размещаться в пространстве микрозадач. , при выполнении события будут выполнены все микрозадачи в пространстве микрозадач, а затем будут выбраны асинхронные задачи в очереди. . . . повторный цикл
Есть картинки и правда (это некрасиво! Не говори некрасиво)
Микрозадачи и макрозадачи
- Тогда обещание микрозадачи (MutationObserver)
- Задачи макросов setInterval, setTimeout, setImmediate(ie), MessageChannel
EventLoop на стороне узла
Придумайте уродливую картинку
Очередное текстовое описание, попробуйте сами запутаться
- Порядок выполнения setTimeout и setImmediate не фиксирован и зависит от времени подготовки узла
Дизайн setImmediate выполняется, когда фаза опроса завершена, то есть фаза проверки; setTimeout предназначен для выполнения, когда фаза опроса простаивает и по истечении установленного времени; но порядок, в котором он выполняется в фазе таймера, зависит от контекста текущего цикла событий, если они вызываются вне асинхронного i Обратный вызов /o (в Поскольку следующим этапом является этап проверки), последовательность выполнения вызова в вводе-выводе неопределенна, и перед выполнением цикла необходимо увидеть трудоемкую ситуацию.
- Каждое поле на приведенном выше рисунке соответствует очереди событий.Когда цикл событий выполняется до определенного этапа, в свою очередь будет выполняться очередь, соответствующая текущему этапу. Когда очередь будет выполнена или количество исполнений превысит строку, она перейдет к следующему этапу.
- Микрозадача — переключить столбец — выполнить
Не говорите глупостей, давайте кодировать
setImmediate(() => {
console.log('setImmediate1')
setTimeout(() => {
console.log('setTimeout1')
}, 0);
})
setTimeout(()=>{
console.log('setTimeout2')
setImmediate(()=>{
console.log('setImmediate2')
})
},0);
//首先setImmediate和setTimeout执行顺序不固定
//所以setImmediate1和setTimeout2,打印顺序不定
//假设 setImmediate1先打印 有两种顺序
//1.执行顺序是 setImmediate1 setTimeout2 setTimeout1 setImmediate2
//2.执行顺序是 setImmediate1 setTimeout2 setImmediate2 setTimeout1
// 1.setImmediate1打印后把setTimeout1放进timer队列 然后执行setTimeout2 这时候把setImmediate2放进check队列中 打印setTimeout2 发现timer中还有setTimeout1 他就会把timer对列中的执行完 才会执行下一队列的代码
//然后打印setTimeout1, 切换对列到check 打印setImmediate2
//2. setImmediate1打印后把setTimeout1放进timer队列 然后执行setTimeout2 这时候把setImmediate2放进check队列中 打印setTimeout2 这个时候node执行过快setTimeout1还没有到时间,所以切换对列执行setImmediate2 然后是setTimeout1
//setTimeout第二个参数虽然是0,但是都有默认时间一般是4ms左右
еще один вопрос
setImmediate(() => {
console.log('setImmediate1')
setTimeout(() => {
console.log('setTimeout1')
}, 0);
})
setTimeout(()=>{
console.log('setTimeout2')
process.nextTick(()=>console.log('nextTick'))
setImmediate(()=>{
console.log('setImmediate2')
})
},0);
//假设setImmediate1先
//setImmediate1 setTimeout2 setTimeout1 nextTick setImmediate2
//setImmediate1 setTimeout2 nextTick setImmediate2 setTimeout1
//微任务会在切换对列时执行 上面从timer对列切换到check对列时nextTick执行
//上面一题明白了这一个也明白了
еще один вопрос
let fs = require('fs');
fs.readFile('./1.txt',function () {
console.log(1);
setTimeout(() => {
console.log('setTimeout')
}, 0);
setImmediate(() => {
console.log('setImmediate')
});
});
//顺序固定 1 setImmediate setTimeout
// 为什么呢?看上面的图 首先readFile肯定是poll对列 执行时把setTimeout setImmediate放到各自队列 然后按上下顺序查找对列 查找到check队列发现有 就把setImmediate打印出 然后顺序检查下一队列close没有 循环 再次从上往下找 直到timer打印setTimeout
Вышеприведенный контент — это mac vscode, который я пробовал.
Есть два типа микрозадач, nextTick и then. Так какая из этих двух задач быстрее?
Promise.resolve('123').then(res=>{
console.log(res);
})
process.nextTick(() => console.log('nextTick'))
//顺序 nextTick 123
//很明显 nextTick快