How does event loop about javascript understand the priority of event queue?

  node.js, question

Recently, I read the relevant information about eventloop in javascript, and I didn’t understand the priority of event queue queue properly. I also asked all great gods to give me some advice.
The first one is by Mr. Ruan YifengDetails of JavaScript Operation Mechanism: Further Discussion on Event Loop; There is a talk about the eventloop loop mechanism, including an event queue queue that holds the callback; of asynchronous tasks. When the execution stack completes, the queue task is read from the queue and executed. Priority is not mentioned here, only that event queue is a FIFO data structure.
And then read the second article of the wave of studentsAdvanced Front End Foundation (XII): Go deep into the core and explain the event cycle mechanism in detail
Mr. Bo said that the queue is divided into macro tasks and micro tasks, and the micro tasks will be executed immediately after the execution of the execution stack, while the macro tasks will not be executed until the next event loop.

One question here is whether there is only one queue queue or macro queue and micro queue in the eventloop loop mechanism. Because they speak differently

Both micro task queue and macro task queue follow FIFO, and the tasks in the queue should be executed in this order when they are read to the execution stack. How should the priority of tasks in the queue be understood? For example, dom event operations, callbacks for ajax requests, and setTimeout are there priorities among them?

console.log('start');
var xhr = new XMLHttpRequest();
var url = 'test.json';
xhr.open('GET', url,true);
xhr.onreadystatechange = function() {
    if (xhr.status == 200 && xhr.readyState == 4) {
        console.log(xhr.responseText)
    }
}
xhr.send();
setTimeout(function() {
    console.log('timeout')
}, 0)
for (var i = 0; i < 3000000000; i加加) {}

var btn = document.querySelector("#btn");
btn.onclick = function() {
    console.log('click')
}

new Promise((reslove, reject) => {
    console.log('promise');
    reslove();
}).then((res) => {
    console.log('promise finish')
})
console.log('end');

Output results:

start
 promise
 end
 promise finish
 click
 bracket
 "test":"aa"
 bracket
 timeout

This is a little different from what I expected. I thought that the ajax callback should have been executed first, because I deliberately stayed for 2-3 seconds to click on that button. In theory, ajax returned first and should have been added to the queue first. As a result, click was output first. . . Is there a priority here?

-This is the split line 2017-04-07 update-

After some ordeal, I checked the blog articles of many big brothers in this field and summarized some knowledge of event loop here:

  1. The first thing to understand is that event loop is implemented by javascript host environment (like browser). js engine does not care about or know event.
    The operation and existence of loop mechanism, he is only responsible for reading events from event queue to execute, he will not and will not know how to push events into event queue, all of which are completed by the host. To understand this first point, it is important to know who is doing it first.

  2. The second point is that a host environment can only have one Event loop, and an event loop can have multiple Task queue, each task having one Task source. Tasks from the same task source can only be placed in one task queue. Tasks from different task sources can be pla ced in different task queues. What the js engine does then is to read the tasks in these queues to execute.

  3. Tasks can be divided into macro tasks and micro tasks. The process and sequence of their execution have been clearly explained by the link given above. I will repeat it roughly: js engine executes script whole code sentence by sentence. When asynchronous tasks are encountered, js’s running environment will push these event tasks to the corresponding queue at the right time, waiting to be executed by js engine. If asynchronous does not generate callback or event tasks, then it will not push into the queue. When js execution stack completes execution, Then he reads the tasks in the micro-task queue and executes them. If there are any new asynchronous tasks in the execution process, he will also process them in the above-mentioned manner. When the micro-task is completed, he will read the tasks in the macro-task queue and execute them. Then he will repeatedly execute them until all the tasks in the queue are executed.
    Macro-task:Script (whole code), settimeout, setinterval, setimmediate, i/o, uirendering;Micro-task:Next ticket, promotions (here refers to the native promotions implemented by the browser), object.observe, mutationobserver

  4. As for the priorities in the queue, there is a general order process. nexttick > promise. then > setttimeout > setimmediate; The priority execution order may also be related to the specific host environment; The Great God of Border Town is also right. For asynchronous, we should not rely on their execution order. Since asynchronous, we should treat it as disorder.

References:
1.What is the relationship between Promise’s queue and setTimeout’s queue?
2.www.w3.org
3.http://stackoverflow.com/ques …
4.https://github.com/youngwind/ …

I don’t know which environment you are running in. I use Chrominum core browser, and when the page is refreshed (the button is displayed), timeout has already been output. The click event must have occurred after that.

https://jsfiddle.net/er5duoaq/