Teknik klasik: single-threading dan JavaScript tak segerak

WBOY
Lepaskan: 2022-02-03 07:00:30
ke hadapan
2002 orang telah melayarinya

Artikel ini membawakan anda pengetahuan yang berkaitan tentang single-threading dan asynchronousness dalam JavaScript saya harap ia akan membantu anda.

Teknik klasik: single-threading dan JavaScript tak segerak

Semasa saya menulis artikel ini, saya juga membaca banyak artikel, tetapi kebanyakannya sangat mudah dan perkara-perkara konsepnya sangat kabur, jadi saya mencari saya mendengar beberapa kursus dan mengambil beberapa nota. Saya akan merumuskannya secara ringkas di sini untuk semakan masa hadapan~

Proses dan Benang

1. Proses : Setelah program dilaksanakan, ia menduduki ruang memori unik ---- anda boleh melihat proses melalui Windows Task Manager; Thread

: Ia adalah

bebas unit pelaksanaan dalam proses; ia adalah proses lengkap pelaksanaan program;

3. Hubungan antara proses dan utas: * Secara amnya terdapat sekurang-kurangnya satu utas berjalan dalam proses: Urut utama

-- selepas proses dimulakan Secara automatik dibuat;

* Berbilang utas juga boleh dijalankan dalam satu proses pada masa yang sama * Data dalam satu proses boleh Untuk berbilang rangkaian untuk dikongsi secara langsung; * Data antara berbilang proses tidak boleh dikongsi secara langsung

4 * Ada yang proses tunggal

* firefox

* Ada yang berbilang proses

* chrome

5. Bagaimana untuk semak sama ada penyemak imbas berbilang proses Apakah proses yang sedang berjalan?

* Pengurus Tugas==> Proses

6 penyemak imbas menjalankan berbilang benang atau tidak?

* Semua dijalankan dalam berbilang benang

Berbilang benang

1. Apa itu single-threaded

Ciri utama bahasa JavaScript ialah ia adalah single-thread, yang bermaksud bahawa ia hanya boleh melakukan satu perkara pada masa yang sama.

2. Mengapa JavaScript berbenang tunggal

Pertama sekali, ini adalah sebab sejarah apabila bahasa JavaScript dicipta, berbilang proses dan berbilang benang seni bina tidak popular dan perkakasan Sokongannya tidak bagus.

Kedua, disebabkan kerumitan multi-threading, operasi multi-threading memerlukan penguncian, dan kerumitan pengekodan akan meningkat.


Perkara terakhir adalah berkaitan dengan tujuannya Sebagai bahasa skrip penyemak imbas, tujuan utama JavaScript adalah untuk berinteraksi dengan pengguna dan mengendalikan DOM Jika DOM dikendalikan pada masa yang sama, tanpa mengunci berbilang benang, ia akhirnya akan membawa kepada Hasil pemaparan DOM tidak dapat diramalkan.

Untuk memanfaatkan kuasa pengkomputeran CPU berbilang teras, HTML5 mencadangkan piawaian Pekerja Web, yang membenarkan skrip JavaScript mencipta berbilang rangkaian, tetapi urutan anak dikawal sepenuhnya oleh rangkaian utama. benang dan tidak boleh mengendalikan DOM. Oleh itu, piawaian baharu ini tidak mengubah sifat berbenang tunggal JavaScript.

Penyegerakan dan tak segerak

//栗子
console.log(1)
console.log(2)
console.log(3)
//输出顺序 1 2 3
Salin selepas log masuk

1. Tugas segerak/tugas tak segerak JS

  • Tugas segerak:
  • dalam. >Pada urutan utama, tugasan
  • yang beratur untuk pelaksanaan hanya boleh dilaksanakan selepas tugasan
  • sebelumnya
  • selesai
Semua tugasan penyegerakan dilaksanakan pada urutan utama , membentuk

tindanan pelaksanaan

(tindanan konteks pelaksanaan).

Tugas tak segerak: Tugas yang dilaksanakan di luar

benang utama

; di luar utas utama, terdapat juga "

barisan tugas

" (baris gilir tugasan ), apabila tugas asynchronous selesai, ia akan dimasukkan ke dalam baris gilir tugas dalam bentuk fungsi panggil balik untuk menunggu Apabila utas utama melahu, utas utama akan pergi ke baris gilir acara keluarkan fungsi panggil balik menunggu dan masukkan ke dalam utas utama yang dilaksanakan. Proses ini dilaksanakan berulang kali untuk membentuk mekanisme gelung acara (Gelung Acara) js. 2. Mengapa JavaScript perlu tidak segerak

Jika semasa pelaksanaan kod JS, sekeping kod tertentu dilaksanakan terlalu lama, kod berikutnya tidak akan dilaksanakan untuk lama, mengakibatkan

menyekat (iaitu tersekat), yang akan menjejaskan pengalaman pengguna.

3. Bagaimana untuk melaksanakan JavaScript tak segerak

1) Timbunan pelaksanaan dan baris gilir tugas Malah, kami telah menyatakan di atas bahawa JS melaksanakan tak segerak melalui gelung peristiwa ;Mari kita fahami beberapa konsep dahulu:

  • JS任务 分为同步任务(synchronous)和异步任务(asynchronous)
  • 同步任务都在 JS引擎线程(主线程) 上执行,形成一个执行栈(call stack)
  • 事件触发线程 管理一个 任务队列(Task Queue)
  • 异步任务 触发条件达成,将 回调事件 放到任务队列(Task Queue)中
  • 执行栈中所有同步任务执行完毕,此时JS引擎线程空闲,系统会读取任务队列,将可运行的异步任务回调事件添加到执行栈中,开始执行

 当一个JS文件第一次执行的时候,js引擎会 解析这段代码,并将其中的同步代码 按照执行顺序加入执行栈中,然后从头开始执行。如果当前执行的是一个方法,那么js会向执行栈中添加这个方法的执行环境,然后进入这个执行环境继续执行其中的代码。当这个执行环境中的代码 执行完毕并返回结果后,js会退出这个执行环境并把这个执行环境销毁,回到上一个方法的执行环境。这个过程反复进行,直到执行栈中的代码全部执行完毕。

栗子 

//(1)
console.log(1)

//(2)
setTimeout(()=>{
    console.log(2)
},100)

//(3)
console.log(3)
Salin selepas log masuk
  1. 先解析整段代码,按照顺序加入到执行栈中,从头开始执行
  2. 先执行(1),是同步的,所以直接打印 1
  3. 执行(2),发现是 setTimeout,于是调用浏览器的方法(webApi)执行,在 100ms后将 console.log(2) 加入到任务队列
  4. 执行(3),同步的,直接打印 3
  5. 执行栈已经清空了,现在检查任务队列,(执行太快的话可能此时任务队列还是空的,没到100ms,还没有将(2)的打印加到任务队列,于是不停的检测,直到队列中有任务),发现有 console.log(2),于是添加到执行栈,执行console.log(2),同步代码,直接打印 2 (如果这里是异步任务,同样会再走一遍循环:-->任务队列->执行栈)

所以结果是 1 3 2;

注意:setTimeout/Promise等我们称之为任务源。而进入任务队列的是他们指定的回调;

2)宏任务(macro task)与微任务(micro task)

 上面的循环只是一个宏观的表述,实际上异步任务之间也是有不同的,分为 宏任务(macro task) 与 微任务(micro task),最新的标准中,他们被称为 task与 jobs

  • 宏任务有哪些:script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering(渲染)
  • 微任务有哪些:process.nextTick, Promise, Object.observe(已废弃), MutationObserver(html5新特性)

下面我们再详细讲解一下执行过程:

 执行栈在执行的时候,会把宏任务放在一个宏任务的任务队列,把微任务放在一个微任务的任务队列,在当前执行栈为空的时候,主线程会 查看微任务队列是否有事件存在。如果微任务队列不存在,那么会去宏任务队列中 取出一个任务 加入当前执行栈;如果微任务队列存在,则会依次执行微任务队列中的所有任务,直到微任务队列为空(同样,是吧队列中的事件加到执行栈执行),然后去宏任务队列中取出最前面的一个事件加入当前执行栈...如此反复,进入循环。

注意:

  • 宏任务和微任务的任务队列都可以有多个
  • 当前执行栈执行完毕时会立刻先处理所有微任务队列中的事件,然后再去宏任务队列中取出一个事件。同一次事件循环中,微任务永远在宏任务之前执行。
  • 不同的运行环境 循环策略可能有不同,这里探讨chrome、node环境

 栗子

//(1)
setTimeout(()=>{
    console.log(1)   // 宏任务
},100)

//(2)
setTimeout(()=>{
    console.log(2)  // 宏任务
},100)

//(3)
new Promise(function(resolve,reject){
    //(4)
    console.log(3)  // 直接打印
    resolve(4)
}).then(function(val){
    //(5)
    console.log(val); // 微任务
})

//(6)
new Promise(function(resolve,reject){
    //(7)
    console.log(5)   // 直接打印
    resolve(6)
}).then(function(val){
    //(8)
    console.log(val);  // 微任务
})

//(9)
console.log(7)  // 直接打印

//(10)
setTimeout(()=>{
    console.log(8) // 宏任务,单比(1)(2)宏任务早
},50)
Salin selepas log masuk

 上面的代码在node和chrome环境的正确打印顺序是 3 5 7 4 6 8 1 2

下面分析一下执行过程:

  1. Semua kod ditambahkan pada timbunan pelaksanaan selepas menghuraikan
  2. Pelaksanaan (1), tugas makro, panggilan webapi setTimeout, kaedah ini akan meletakkan fungsi panggil balik ke dalam baris gilir tugas tugas makro selepas 100ms
  3. Laksanakan (2), sama seperti (1), tetapi lewat sedikit daripada (1)
  4. Laksanakan (3), laksanakan Janji baharu secara serentak, kemudian laksanakan (4), cetak 3 secara langsung, dan kemudian selesaikan(4), kemudian .then(), masukkan (5) ke dalam baris gilir tugasan microtask
  5. dan laksanakan (6), sama seperti di atas, cetak pertama 5, kemudian laksanakan resolve(6), kemudian .then( )Kandungan di dalam (8) ditambahkan pada baris gilir tugasan microtask
  6. laksana (9), menyegerakkan kod dan terus mencetak 7
  7. melaksanakan (10), sama seperti (1) dan (2) , tetapi masanya lebih singkat, console callback.log(8) akan ditambahkan pada baris gilir tugas tugas makro selepas 50ms
  8. Sekarang timbunan pelaksanaan dikosongkan, mula semak baris gilir tugasan mikro dan cari (5), tambahkannya pada timbunan pelaksanaan Timbunan kod segerak, terus cetak 4
  9. Baris gilir tugasan telah dilaksanakan semula dan semak tugasan mikro baris gilir, dan cari (8), cetak 6
  10. Baris gilir tugasan telah dilaksanakan sekali lagi, semak tugasan mikro Tiada tugas dalam baris gilir Semak baris gilir tugasan makro sekali lagi. anda akan mendapati console.log(8) berada dalam baris gilir tugasan makro, jadi cetak 8
  11. dan cetak 1 2
  12. dalam urutan

Nota: Kerana pemaparan juga merupakan makro tugasan, pemaparan perlu dilaksanakan selepas timbunan pelaksanaan telah dilaksanakan Oleh itu, jika terdapat beberapa kod yang menukar gaya yang sama secara serentak dalam timbunan pelaksanaan pada masa yang sama, hanya Render yang terakhir.

Cadangan berkaitan: Tutorial pembelajaran javascript

Atas ialah kandungan terperinci Teknik klasik: single-threading dan JavaScript tak segerak. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:csdn.net
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!