Rumah  >  Artikel  >  hujung hadapan web  >  Mari kita bincangkan tentang "tindak balas kimia" yang akan berlaku apabila menggunakan await dalam gelung JS

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

藏色散人
藏色散人ke hadapan
2023-03-02 17:22:281732semak imbas

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())

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);
  })
})

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)
}

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)
})

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>

, 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()
const logByWhile = async () => {
  let i = 0
  while (i !== arr.length) {
    await sleep(1000)
    console.log(arr[i]);
    i++
  }
}
logByWhile()

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)
}
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);
}
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!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam