Mengapakah perintah pelaksanaan JavaScript Promise tidak linear seperti yang dijangkakan?

DDD
Lepaskan: 2024-10-24 13:23:31
asal
501 orang telah melayarinya

Why is the JavaScript Promise execution order not linear as expected?

Perintah Pelaksanaan Janji JavaScript

Masalah

Pertimbangkan kod JavaScript berikut yang menggunakan janji:

<code class="javascript">Promise.resolve('A')
  .then(function(a){console.log(2, a); return 'B';})
  .then(function(a){
     Promise.resolve('C')
       .then(function(a){console.log(7, a);})
       .then(function(a){console.log(8, a);});
     console.log(3, a);
     return a;})
  .then(function(a){
     Promise.resolve('D')
       .then(function(a){console.log(9, a);})
       .then(function(a){console.log(10, a);});
     console.log(4, a);})
  .then(function(a){
     console.log(5, a);});
console.log(1);
setTimeout(function(){console.log(6)},0);</code>
Salin selepas log masuk

Outputnya adalah seperti berikut:

<code class="text">1
2 "A"
3 "B"
7 "C"
4 "B"
8 undefined
9 "D"
5 undefined
10 undefined
6</code>
Salin selepas log masuk

Soalannya ialah mengenai susunan pelaksanaan, khususnya nombor 1, 2, 3, 7, dan seterusnya. Mengapakah ia bukan susunan linear 1, 2, 3, 4, ...?

Jawapan

Perintah Perlaksanaan Janji

Janji JavaScript mengikut peraturan pelaksanaan tertentu:

  1. Pelaksanaan Asynchronous: Pengendali Janji .then() dilaksanakan secara tidak segerak selepas urutan pelaksanaan semasa selesai. Ini adalah untuk memastikan operasi tak segerak dapat diselesaikan tanpa menyekat utas utama.
  2. Janji Bersarang: Mencipta janji baharu di dalam pengendali .then() tanpa mengembalikannya mewujudkan rantai janji bebas. Rantai janji bebas ini tidak mempunyai perintah pelaksanaan yang boleh diramal.

Analisis Pesanan

Dalam kod yang diberikan:

  • Janji awal diselesaikan serta-merta, jadi pengendali .then()nya (console.log(2, a)) berjalan secara tidak segerak selepas console.log(1) (baris 23).
  • Pengendali .then() pada baris 4 mencipta rantai janji bebas yang berjalan secara tidak segerak.
  • Pengendali .then() pada baris 12 mencipta satu lagi rantai janji bebas yang berjalan secara tidak segerak.
  • Pengendali .then() pada baris 19 mencipta satu lagi rantai janji bebas yang berjalan secara tidak segerak.
  • setTimeout() menetapkan panggilan balik yang dijalankan selepas urutan pelaksanaan semasa selesai, tetapi ia tidak dijamin untuk dijalankan sebelum atau selepas pengendali promise .then().

Perlaksanaan Bukan Deterministik

Memandangkan rantai janji bebas yang dibuat dalam pengendali .then() tidak mempunyai perintah pelaksanaan yang boleh diramal, susunan 3, 7, 4, 8, 9, 5, 10 bergantung pada pelaksanaan enjin janji khusus.

Syor

Untuk memastikan perintah pelaksanaan khusus untuk operasi tak segerak, disyorkan untuk:

  1. Elakkan membuat rantai janji bebas dalam .kemudian () pengendali.
  2. Pautkan rantai janji untuk memastikan perintah pelaksanaan tertentu.

Dalam contoh yang diberikan, mengembalikan janji Promise.resolve('C') daripada .then( ) pengendali pada baris 4 akan memautkan rantai janji dan menghasilkan susunan pelaksanaan berurutan yang dijangkakan.

Atas ialah kandungan terperinci Mengapakah perintah pelaksanaan JavaScript Promise tidak linear seperti yang dijangkakan?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber: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
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!