Mari kita bincangkan tentang 'tindak balas kimia' yang akan berlaku apabila menggunakan await dalam gelung JS

藏色散人
Lepaskan: 2023-03-02 19:56:11
ke hadapan
1716 orang telah melayarinya

Artikel ini memberi anda pengetahuan yang berkaitan tentang gelung JavaScript terutamanya tentang cara menggunakan gelung js dan analisis hasil. Saya harap ia berguna kepada semua orang.

Kata Pengantar

Bagaimana soalan ini timbul? Pada suatu hari, semasa belajar tentang pengetahuan tak segerak, saya menemui soalan seperti ini: Menggunakan Promise, keluarkan nilai dalam tatasusunan setiap saat

const arr = [1, 2, 3]
arr.reduce((pre, cur) => {
  return pre.then(() => {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve(console.log(cur))
      }, 1000);
    })
  })
}, Promise.resolve())
Salin selepas log masuk

Kemudian kod ini agak mudah difahami, bersamaan dengan

Promise.resolve().then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(1))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(2))
    }, 1000);
  })
}).then(() => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(console.log(3))
    }, 1000);
  })
})
Salin selepas log masuk

Selepas membaca ini, saya berfikir bahawa jika saya berhenti selama satu saat selepas setiap nilai output dalam gelung, ia boleh diselesaikan, jadi saya datang dengan kod berikut

const arr = [1, 2, 3]
const sleep = (ms) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}
for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
  await sleep(1000)
}
Salin selepas log masuk

Hasil cetakan juga selaras dengan jangkaan Di sini saya mempunyai soalan pertama: Tidak menunggu perlu digunakan dengan async? Bagaimana ia boleh digunakan secara bersendirian di sini? (Jika anda tidak percaya saya, cuba letakkan kod dalam konsol penyemak imbas)

Kemudian saya menukar kepada forEach dan mendapati bahawa kesannya tidak tercapai sama sekali Soalan kedua timbul: mengapa menunggu forEach gagal?

arr.forEach(async item => {
  console.log(item);
  await sleep(1000)
})
Salin selepas log masuk

Dengan dua soalan ini, mulakan belajar dan mencari jawapan.

await in for loop

Saya ingat ada pepatah bila belajar async/wait, wait hanya boleh digunakan bersama dengan async Sebenarnya ayat ini Ada tiada yang salah dengan itu. Kemudian mengapa saya boleh menulis menunggu terus di hadapan? Kerana saya menulisnya terus dalam konsol penyemak imbas Apabila kita menulis kod dalam editor, kita mesti menggunakan async

 <script>  
   const arr = [1, 2, 3]
   const sleep = (ms) => {
     return new Promise((resolve, reject) => {
       setTimeout(() => {
         resolve()
       }, ms)
     })
   }
   const logByOneSecond = async () => {
     for (let i = 0; i < arr.length; i++) {
       console.log(arr[i]);
       await sleep(1000)
     }
   }   
   logByOneSecond()
 </script>
Salin selepas log masuk

, jadi ini dianggap menyusahkan. Memang gurau je haha ​​tapi bila jumpa benda yang aku tak faham, ia bagi aku cara lain untuk berfikir.

Baiklah, seperti yang dinyatakan di atas, await memang memainkan peranannya, membenarkan JS menunggu sehingga hasil pemprosesan dikembalikan dengan janji, dan kemudian terus melaksanakan, kemudian untuk...daripada, sementara juga boleh

const logByForof = async () => {
  for (const item of arr) {
    console.log(item);
    await sleep(1000)
  }    
}
logByForof()
Salin selepas log masuk
const logByWhile = async () => {
  let i = 0
  while (i !== arr.length) {
    await sleep(1000)
    console.log(arr[i]);
    i++
  }
}
logByWhile()
Salin selepas log masuk

Hasilnya juga selaras dengan jangkaan Anda boleh menggunakan tunggu dalam gelung dan mencapai kesan

tunggu dalam gelung forEach

<. 🎜 >Seperti pada mulanya, kesan yang dijangkakan tidak dicapai dalam forEach terlebih dahulu, keputusan diperoleh: async dan wait in forEach adalah tidak sah.

Kemudian penjelasan yang saya lihat adalah seperti berikut:

  • untukSetiap dalam JavaScript tidak menyokong kesedaran janji, juga tidak menyokong async dan menunggu, jadi anda tidak boleh menggunakan await dalam forEach .

  • map/forEach digunakan secara dalaman semasa digabungkan dengan panggilan balik untuk melaksanakan fungsi, menunggu tidak akan menunggu untuk pelaksanaan panggilan balik

  • forEach hanya menyokong segerak kod

Pernyataan kedua adalah untuk memudahkan pseudokod, seperti berikut

while(index < arr.length){
  callback(item, index)
}
Salin selepas log masuk
map/forEach ialah fungsi panggil balik pelaksanaan yang mudah dan tidak akan mengendalikan Keadaan tak segerak. Iaitu: map/forEach akan mencipta berbilang fungsi panggil balik pada masa yang sama Berbilang fungsi panggil balik ditambah dengan async mereka sendiri dan menunggu, seperti yang ditunjukkan di bawah

async ()=>{
  await sleep(1000); 
} 
async ()=>{ 
  await sleep(1000);
} 
async ()=>{ 
  await sleep(1000);
}
Salin selepas log masuk
Setiap fungsi adalah bebas, dan begitu juga fungsi masing-masing. panggilan balik. Bebas; permintaan tidak segerak dan tidak berkaitan antara satu sama lain, jadi pesanan tidak boleh dijamin

Ringkasan

Menyemak penggunaan tak segerak/menunggu dalam kenyataan gelung untuk digunakan: Untuk gelung untuk biasa, semua menunggu dipanggil secara bersiri dan boleh digunakan dengan yakin, termasuk sementara, untuk-dalam, untuk-daripada, dsb. tetapi dalam kaedah tatasusunan dengan panggilan balik, seperti untukSetiap, peta, Penapis, mengurangkan, dan lain-lain mempunyai banyak kesan sampingan, jadi sebaiknya jangan gunakan tunggu.

[Pembelajaran yang disyorkan:

Tutorial JavaScript Lanjutan]

Atas ialah kandungan terperinci Mari kita bincangkan tentang 'tindak balas kimia' yang akan berlaku apabila menggunakan await dalam gelung JS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:juejin.im
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!