Event Loop--イベントループ
1.すべての同期タスクはメインスレッド上で実行され、実行スタックを形成します。
2.そして、非同期タスクは非同期処理モジュールに配置されます。非同期タスクが実行結果を持つと、関数はタスクキューに移動します。
3.実行スタック内の同期タスクがすべて実行されると、エンジンはタスク・キューを読み込み、タスク・キュー内の最初のタスクを実行スタックに押し込んで実行します。メイン・スレッドが空である限り、メイン・スレッドはタスク・キューを読み込み、イベント・ループと呼ばれる処理を繰り返します。
マクロタスクとマイクロタスク
キュー内のタスクは非同期処理で完了し、非同期タスクはマクロタスクとマイクロタスクに分けられます。マクロ・タスクはキューに入りますが、マイクロ・タスクは別のキューに入り、マクロ・タスクよりもマイクロ・タスクが優先されます。
マクロ・タスク:script、setTimeout、setInterval、I/O、event、postMessage、MessageChannel、setImmediate(Node.js)
マイクロタスク:Promise.thenMutaionObserver, プロセス.nextTick (Node.js)
process.nextTickで指定された非同期タスクは、すべての非同期タスクに対して常に発生するため、process.nextTickが最初に実行されます。
タスク・キューに入れる条件 ------ 1.
setTimeout(()=>{
console.log(1)
},0)
Promise.resolve().then(()=>{
console.log(2)
})
Promise.resolve().then(()=>{
console.log(4)
})
console.log(3)
//3 2 4 1
同期タスクが最初に実行され、次にマイクロタスク、最後にマクロタスクが実行されます。
setTimeout(()=>{
console.log(1)
},0)
new Promise((resolve)=>{
console.log(2) //実行関数は同期的に実行される
resolve()
}).then(()=>{
console.log(3)
}).then(()=>{
console.log(4)
})
console.log(5)
//2 5 3 4 1
const first = () => (new Promise((resolve, reject) => {
console.log(3)
let p = new Promise((resolve, reject) => {
console.log(7)
setTimeout(() => {
console.log(5)
resolve(6)//は無視される。なぜなら、ステートはすでに変更されているからである!
}, 0)
resolve(1)
})
resolve(2)
p.then((arg) => {
console.log(arg)
})
}))
first().then((arg) => {
console.log(arg)
})
console.log(4)
//3 7 4 1 2 5
最初の()の最初の実行は、最初に同期コードの内部を参照してくださいので、最初の出力だけでなく、pの内部も同期実行されるため、それはまた、同期実行され、その後、印刷し、タイマーを起動すると、マクロタスクに入れられますresolve(1)もすぐに実行され、pの状態が変更されたことを意味し、p.thenコールバック関数が最初に実行され、arg = 1のマイクロキューに入れられ、その後、resolve(2)を実行し、マイクロキューに入れられ、その後、マイクロキュータスクを実行し、出力、出力、出力、出力、出力。キューに入れ、resolve(2)を実行し、arg=2をマイクロキューに入れ、マイクロキュータスクを実行し、output、output、output。
setTimeout(() => {
console.log("0")
}, 0)
new Promise((resolve, reject) => {
console.log("1")
resolve()
}).then(() => {
console.log("2")
new Promise((resolve, reject) => {
console.log("3")
resolve()
}).then(() => {
console.log("4")
}).then(() => {
console.log("5")
})
}).then(() => {
console.log("6")
})
new Promise((resolve, reject) => {
console.log("7")
resolve()
}).then(() => {
console.log("8")
})
//1 7 2 3 8 4 6 5 0
console.log("2")...console.log("5")
タイマーをオンにして、console.log("0")をマクロキューに入れ、同期的にconsole.log("1")を実行し、resolve()を実行してマイクロキューに入れ、すぐにconsole.log("7")を実行してマイクロキューにconsole.log("8")を入れます。
初期化コード実行結果 //1 7 マクロタスクキュー[0] マイクロタスクキュー[2,8]
console.log("2")を取り出して実行し、すぐにconsole.log("3")を実行し、resolve()を呼び出すと、console.log("4")がマイクロキューに入り、console.log("5")はキューに入りませんが、関数はすでに結果を出しており、状態を変更し、console.log("6") をマイクロキューに入れます。
実行結果 //1 7 2 3 マクロタスクキュー[0] マイクロタスクキュー[8,4,6]
console.log("8")を取り出して実行、console.log("4")を取り出して実行、console.log("5")をマイクロキューに入れ、console.log("6")を取り出して実行、console.log("5")を取り出して実行、console.log("0")を取り出して実行。