Rumah hujung hadapan web tutorial js 细说JavaScript事件循环机制-第二讲

细说JavaScript事件循环机制-第二讲

Mar 07, 2018 pm 03:26 PM
javascript js mekanisme

我们继续来讲JavaScript中的事件循环机制,第一讲的JavaScript事件循环机制并没有讲完,我们现在继续接着讲,对JavaScript事件循环机制的继续来看本篇文章吧!

在上一篇文章里面我大致介绍了JavaScript的事件循环机制,但是最后还留下了一段代码和几个问题。

那我们先从这段代码开始看哇

(function test() {
    setTimeout(function() {console.log(4)}, 0);
    new Promise(function executor(resolve) {
        console.log(1);
        for( var i=0 ; i<10000 ; i++ ) {
            i == 9999 && resolve();
        }
        console.log(2);
    }).then(function() {
        console.log(5);
    });
    console.log(3);
})()
Salin selepas log masuk
Salin selepas log masuk

在这段代码里面,setTimeout和Promise都被称之为任务源,来自不同任务源的回调函数会被放进不同的任务队列里面。

setTimeout的回调函数被放进setTimeout的任务队列之中。而对于Promise,它的回调函数并不是传进去的executer函数,而是其异步执行的then方法里面的参数,被放进Promise的任务队列之中。也就是说Promise的第一个参数并不会被放进Promise的任务队列之中,而会在当前队列就执行。

其中setTimeout和Promise的任务队列叫做macro-task(宏任务),当然如我们所想,还有micro-task(微任务)。

  1. macro-task包括:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering。

  2. micro-task包括:process.nextTick, Promises, Object.observe, MutationObserver

其中上面的setImmediate和process.nextTick是Node.JS里面的API,浏览器里面并没有,这里就当举例,不必纠结具体是怎么实现的。

事件循环的顺序是从script开始第一次循环,随后全局上下文进入函数调用栈,碰到macro-task就将其交给处理它的模块处理完之后将回调函数放进macro-task的队列之中,碰到micro-task也是将其回调函数放进micro-task的队列之中。直到函数调用栈清空只剩全局执行上下文,然后开始执行所有的micro-task。当所有可执行的micro-task执行完毕之后。循环再次执行macro-task中的一个任务队列,执行完之后再执行所有的micro-task,就这样一直循环。

分析执行过程

下面分析的思路按照波同学之前所写的深入核心,详解事件循环机制中的思路进行分析。

以之前的栗子作为分析的对象,来分析事件循环机制究竟是怎么执行代码的

(function test() {
    setTimeout(function() {console.log(4)}, 0);
    new Promise(function executor(resolve) {
        console.log(1);
        for( var i=0 ; i<10000 ; i++ ) {
            i == 9999 && resolve();
        }
        console.log(2);
    }).then(function() {
        console.log(5);
    });
    console.log(3);
})()
Salin selepas log masuk
Salin selepas log masuk

注意下面所有图中的setTimeout任务队和最后的函数调用栈中存放的都是setTimeout的回调函数,并不是整个setTimeout定时器

PAI3JG45K0S21M[8AP}I8AV.png

1.首先,script任务源先执行,全局上下文入栈。

@F7}R(TMXRTG@YA}@19Y%5B.png

2.script任务源的代码在执行时遇到setTimeout,作为一个macro-task,将其回调函数放入自己的队列之中。

(Y7DEM(J8M45`MW7I`]ON3P.png

3.script任务源的代码在执行时遇到Promise实例。Promise构造函数中的第一个参数是在当前任务直接执行不会被放入队列之中,因此此时输出 1 。

0`@U79F427SBFX(][G`QC12.png

(1UH@Q5OX430O7G(O~ZA}JP.png

4.在for循环里面遇到resolve函数,函数入栈执行之后出栈,此时Promise的状态变成Fulfilled。代码接着执行遇到console.log(2),输出2。

5IIZM~S$L@XZBD$%U$9G408.png

5.接着执行,代码遇到then方法,其回调函数作为micro-task入栈,进入Promise的任务队列之中。

(U`W$DPY7P8)LC_70CQ)K1G.png

6.代码接着执行,此时遇到console.log(3),输出3。

T@ZO_@8L@%YL6A2Q12~O)9A.pngYB6H8HXS8{8)(N]N80VB3MH.png

7.输出3之后第一个宏任务script的代码执行完毕,这时候开始开始执行所有在队列之中的micro-task。then的回调函数入栈执行完毕之后出栈,这时候输出5

WDQDKWM9Q}S56O(1WB7HF$O.png

8.这时候所有的micro-task执行完毕,第一轮循环结束。第二轮循环从setTimeout的任务队列开始,setTimeout的回调函数入栈执行完毕之后出栈,此时输出4。

总结

总的来说就是:

1、不同的任务会放进不同的任务队列之中。

2、先执行macro-task,等到函数调用栈清空之后再执行所有在队列之中的micro-task。

3、等到所有micro-task执行完之后再从macro-task中的一个任务队列开始执行,就这样一直循环。

4、当有多个macro-task(micro-task)队列时,事件循环的顺序是按上文macro-task(micro-task)的分类中书写的顺序执行的。

测试

说到这里,我们应该都明白了,下面是一个复杂的代码段(改自深入核心,详解事件循环机制),里面有混杂着的micro-task和macro-task,自己画图试试流程哇,然后再用node执行看看输出的顺序是否一致。

console.log(&#39;golb1&#39;);
setImmediate(function() {
    console.log(&#39;immediate1&#39;);
    process.nextTick(function() {
        console.log(&#39;immediate1_nextTick&#39;);
    })
    new Promise(function(resolve) {
        console.log(&#39;immediate1_promise&#39;);
        resolve();
    }).then(function() {
        console.log(&#39;immediate1_then&#39;)
    })
})
setTimeout(function() {
    console.log(&#39;timeout1&#39;);
    process.nextTick(function() {
        console.log(&#39;timeout1_nextTick&#39;);
    })
    new Promise(function(resolve) {
        console.log(&#39;timeout1_promise&#39;);
        resolve();
    }).then(function() {
        console.log(&#39;timeout1_then&#39;)
    })
    setTimeout(function() {
    	console.log(&#39;timeout1_timeout1&#39;);
    process.nextTick(function() {
        console.log(&#39;timeout1_timeout1_nextTick&#39;);
    })
    setImmediate(function() {
    	console.log(&#39;timeout1_setImmediate1&#39;);
    })
    });
})
new Promise(function(resolve) {
    console.log(&#39;glob1_promise&#39;);
    resolve();
}).then(function() {
    console.log(&#39;glob1_then&#39;)
})
process.nextTick(function() {
    console.log(&#39;glob1_nextTick&#39;);
})
Salin selepas log masuk

讲到这里我们的细说JavaScript事件循环机制也就正式讲完了,看不懂了两篇结合起来看看,练练即可!

先看看我吧:

细说JavaScript事件循环机制-第一讲

Atas ialah kandungan terperinci 细说JavaScript事件循环机制-第二讲. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Disyorkan: Projek pengesanan dan pengecaman muka sumber terbuka JS yang sangat baik Disyorkan: Projek pengesanan dan pengecaman muka sumber terbuka JS yang sangat baik Apr 03, 2024 am 11:55 AM

Teknologi pengesanan dan pengecaman muka adalah teknologi yang agak matang dan digunakan secara meluas. Pada masa ini, bahasa aplikasi Internet yang paling banyak digunakan ialah JS Melaksanakan pengesanan muka dan pengecaman pada bahagian hadapan Web mempunyai kelebihan dan kekurangan berbanding dengan pengecaman muka bahagian belakang. Kelebihan termasuk mengurangkan interaksi rangkaian dan pengecaman masa nyata, yang sangat memendekkan masa menunggu pengguna dan meningkatkan pengalaman pengguna termasuk: terhad oleh saiz model, ketepatannya juga terhad. Bagaimana untuk menggunakan js untuk melaksanakan pengesanan muka di web? Untuk melaksanakan pengecaman muka di Web, anda perlu biasa dengan bahasa dan teknologi pengaturcaraan yang berkaitan, seperti JavaScript, HTML, CSS, WebRTC, dll. Pada masa yang sama, anda juga perlu menguasai visi komputer yang berkaitan dan teknologi kecerdasan buatan. Perlu diingat bahawa kerana reka bentuk bahagian Web

Petua Pembangunan PHP dan JS: Kuasai Kaedah Melukis Carta Lilin Stok Petua Pembangunan PHP dan JS: Kuasai Kaedah Melukis Carta Lilin Stok Dec 18, 2023 pm 03:39 PM

Dengan perkembangan pesat kewangan Internet, pelaburan saham telah menjadi pilihan semakin ramai orang. Dalam perdagangan saham, carta lilin adalah kaedah analisis teknikal yang biasa digunakan Ia boleh menunjukkan trend perubahan harga saham dan membantu pelabur membuat keputusan yang lebih tepat. Artikel ini akan memperkenalkan kemahiran pembangunan PHP dan JS, membawa pembaca memahami cara melukis carta lilin saham dan menyediakan contoh kod khusus. 1. Memahami Carta Lilin Saham Sebelum memperkenalkan cara melukis carta lilin saham, kita perlu memahami dahulu apa itu carta lilin. Carta candlestick telah dibangunkan oleh orang Jepun

Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Tutorial JavaScript Mudah: Cara Mendapatkan Kod Status HTTP Jan 05, 2024 pm 06:08 PM

Tutorial JavaScript: Bagaimana untuk mendapatkan kod status HTTP, contoh kod khusus diperlukan: Dalam pembangunan web, interaksi data dengan pelayan sering terlibat. Apabila berkomunikasi dengan pelayan, kami selalunya perlu mendapatkan kod status HTTP yang dikembalikan untuk menentukan sama ada operasi itu berjaya dan melaksanakan pemprosesan yang sepadan berdasarkan kod status yang berbeza. Artikel ini akan mengajar anda cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan menyediakan beberapa contoh kod praktikal. Menggunakan XMLHttpRequest

Hubungan antara js dan vue Hubungan antara js dan vue Mar 11, 2024 pm 05:21 PM

Hubungan antara js dan vue: 1. JS sebagai asas pembangunan Web; 2. Kebangkitan Vue.js sebagai rangka kerja hadapan 3. Hubungan pelengkap antara JS dan Vue; Vue.

Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Bagaimana untuk mendapatkan kod status HTTP dalam JavaScript dengan cara yang mudah Jan 05, 2024 pm 01:37 PM

Pengenalan kepada kaedah mendapatkan kod status HTTP dalam JavaScript: Dalam pembangunan bahagian hadapan, kita selalunya perlu berurusan dengan interaksi dengan antara muka bahagian belakang, dan kod status HTTP adalah bahagian yang sangat penting daripadanya. Memahami dan mendapatkan kod status HTTP membantu kami mengendalikan data yang dikembalikan oleh antara muka dengan lebih baik. Artikel ini akan memperkenalkan cara menggunakan JavaScript untuk mendapatkan kod status HTTP dan memberikan contoh kod khusus. 1. Apakah kod status HTTP bermakna kod status HTTP apabila penyemak imbas memulakan permintaan kepada pelayan, perkhidmatan tersebut

js untuk memuat semula halaman semasa js untuk memuat semula halaman semasa Jan 24, 2024 pm 03:58 PM

js kaedah untuk menyegarkan halaman semasa: 1. location.reload(); 2. location.href; Pengenalan terperinci: 1. location.reload(), gunakan kaedah location.reload() untuk memuat semula halaman semasa; 2. location.href, anda boleh memuat semula halaman semasa dengan menetapkan atribut location.href, dsb.

Pemahaman mendalam tentang mekanik pengiraan semula susun atur CSS dan pemaparan Pemahaman mendalam tentang mekanik pengiraan semula susun atur CSS dan pemaparan Jan 26, 2024 am 09:11 AM

Aliran semula dan cat semula CSS adalah konsep yang sangat penting dalam pengoptimuman prestasi halaman web. Apabila membangunkan halaman web, memahami cara kedua-dua konsep ini berfungsi boleh membantu kami meningkatkan kelajuan tindak balas dan pengalaman pengguna halaman web. Artikel ini akan menyelidiki mekanik aliran semula dan mengecat semula CSS, serta memberikan contoh kod khusus. 1. Apakah aliran semula CSS? Apabila keterlihatan, saiz atau kedudukan elemen dalam struktur DOM berubah, penyemak imbas perlu mengira semula dan menggunakan gaya CSS dan kemudian susun atur semula

Era AI JS sudah tiba! Era AI JS sudah tiba! Apr 08, 2024 am 09:10 AM

Pengenalan kepada JS-Torch JS-Torch ialah perpustakaan JavaScript pembelajaran mendalam yang sintaksnya hampir sama dengan PyTorch. Ia mengandungi objek tensor berfungsi sepenuhnya (boleh digunakan dengan kecerunan yang dijejaki), lapisan dan fungsi pembelajaran mendalam, dan enjin pembezaan automatik. JS-Torch sesuai untuk penyelidikan pembelajaran mendalam dalam JavaScript dan menyediakan banyak alatan dan fungsi yang mudah untuk mempercepatkan pembangunan pembelajaran mendalam. Image PyTorch ialah rangka kerja pembelajaran mendalam sumber terbuka yang dibangunkan dan diselenggara oleh pasukan penyelidik Meta. Ia menyediakan set alat dan perpustakaan yang kaya untuk membina dan melatih model rangkaian saraf. PyTorch direka bentuk untuk menjadi ringkas, fleksibel dan mudah digunakan, dan ciri graf pengiraan dinamiknya menjadikan

See all articles