Rumah  >  Artikel  >  hujung hadapan web  >  Mengapakah perintah pelaksanaan JavaScript Promise tidak linear seperti yang dijangkakan?

Mengapakah perintah pelaksanaan JavaScript Promise tidak linear seperti yang dijangkakan?

DDD
DDDasal
2024-10-24 13:23:31502semak imbas

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>

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>

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!

Kenyataan:
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