
Selamat siang teman-teman!
Saya mempersembahkan untuk Anda terjemahan dari artikel Apal Shah,
"Kesalahan umum Javascript Promise yang harus diketahui dan dihindari oleh setiap pemula .
"Janji-janji JavaScript Yang Umum Yang Harus Diketahui Semua Orang
Saya ingin tahu tentang kesalahan ini ketika saya mempelajari JavaScript dan janji-janji.
Setiap kali beberapa pengembang memanggil saya dan mengeluh bahwa kodenya tidak berfungsi atau sedang dieksekusi lambat, saya pertama-tama memperhatikan kesalahan-kesalahan ini. Ketika saya mulai pemrograman 4 tahun yang lalu, saya tidak tahu tentang mereka dan terbiasa mengabaikannya. Namun, setelah ditugaskan ke proyek yang memproses sekitar satu juta permintaan dalam beberapa menit, saya tidak punya pilihan selain mengoptimalkan kode saya (karena kami mencapai tingkat di mana penskalaan vertikal lebih lanjut menjadi tidak mungkin).
Oleh karena itu, dalam artikel ini saya ingin berbicara tentang kesalahan paling umum ketika bekerja dengan janji di JS, yang banyak yang tidak memperhatikan.
Kesalahan # 1. Menggunakan blok coba / tangkap di dalam Janji
Menggunakan blok coba / tangkap di dalam janji tidak praktis, karena jika kode Anda melempar kesalahan (di dalam janji), itu akan dicegat oleh penangan kesalahan dari janji itu sendiri.
Ini tentang apa ini:
new Promise((resolve, reject) => { try { const data = someFunction()
Alih-alih, biarkan kode menangani kesalahan di luar janji:
new Promise((resolve, reject) => { const data = someFunction()
Ini akan selalu berhasil, kecuali seperti yang dijelaskan di bawah ini.
Kesalahan No. 2. Menggunakan fungsi asinkron di dalam Janji
Saat menggunakan fungsi asinkron, beberapa efek samping yang tidak menyenangkan terjadi dalam Janji.
Misalkan Anda memutuskan untuk melakukan beberapa tugas tidak sinkron, tambahkan kata kunci "async" ke janji, dan kode Anda melempar kesalahan. Namun, sekarang Anda tidak dapat menangani kesalahan ini dengan .catch () atau menunggu:
Setiap kali saya menemukan fungsi asinkron di dalam sebuah janji, saya mencoba untuk memisahkannya. Dan saya mendapatkannya di 9 dari 10 kasus. Namun, ini tidak selalu memungkinkan. Dalam hal ini, Anda tidak punya pilihan selain menggunakan blok coba / tangkap di dalam janji (ya, ini bertentangan dengan kesalahan pertama, tetapi ini adalah satu-satunya jalan keluar):
new Promise(async(resolve, reject) => { try { throw new Error('message') } catch(error) { reject(error) } }).catch(e => console.log(e.message))
Nomor kesalahan 3. Lupakan .catch ()
Ini adalah salah satu kesalahan yang bahkan tidak Anda duga ada hingga pengujian dimulai. Atau, jika Anda seorang ateis yang tidak percaya pada tes, kode Anda pasti akan macet dalam
produksi . Karena produksi secara ketat mengikuti
hukum Murphy , yang mengatakan: "Apa pun yang bisa salah akan salah" (Anda dapat menerjemahkan ini: "Jika ada sesuatu yang salah, itu akan terjadi"; analogi dalam bahasa Rusia adalah "hukum kekejaman" - kira-kira.
Untuk membuat kode lebih elegan, Anda bisa membungkus janji dalam try / catch alih-alih menggunakan .then (). Catch ().
Kesalahan No. 4. Jangan gunakan Promise.all ()
Promise.all () adalah teman Anda.
Jika Anda adalah pengembang profesional, Anda mungkin mengerti apa yang ingin saya katakan. Jika Anda memiliki beberapa janji yang tidak bergantung satu sama lain, Anda dapat menjalankannya secara bersamaan. Secara default, janji dieksekusi secara paralel, namun jika Anda perlu mengeksekusinya secara berurutan (menggunakan menunggu), itu akan membutuhkan banyak waktu. Promise.all () dapat sangat mengurangi latensi:
const {promisify} = require('util') const sleep = promisify(setTimeout) async function f1() { await sleep(1000) } async function f2() { await sleep(2000) } async function f3() { await sleep(3000) }
Sekarang dengan Promise.all ():
(async() => { console.time('concurrent') await Promise.all([f1(), f2(), f3()]) console.timeEnd('concurrent')
Kesalahan No. 5. Penggunaan Promise.race () secara tidak benar
Promise.race () tidak selalu membuat kode Anda lebih cepat.
Ini mungkin terlihat aneh, tetapi sebenarnya begitu. Saya tidak mengatakan bahwa Promise.race () adalah metode yang tidak berguna, tetapi Anda harus memahami dengan jelas mengapa Anda menggunakannya.
Misalnya, Anda dapat menggunakan Promise.race () untuk menjalankan kode setelah menyelesaikan semua janji. Tetapi ini tidak berarti bahwa pelaksanaan kode yang mengikuti janji-janji akan segera dimulai setelah resolusi salah satunya. Promise.race () akan menunggu semua janji untuk diselesaikan dan baru kemudian melepaskan aliran:
const {promisify} = require('util') const sleep = promisify(setTimeout) async function f1() { await sleep(1000) } async function f2() { await sleep(2000) } async function f3() { await sleep(3000) } (async() => { console.time('race') await Promise.race([f1(), f2(), f3()]) })(); process.on('exit', () => { console.timeEnd('race')
Kesalahan No. 6. Penyalahgunaan Janji
Janji membuat kode lebih lambat, jadi jangan menyalahgunakannya.
Seringkali Anda harus melihat pengembang menggunakan rantai panjang .then () untuk membuat kode mereka terlihat lebih baik. Anda tidak akan punya waktu untuk mengedipkan mata, karena rantai ini menjadi terlalu panjang. Untuk memverifikasi secara visual konsekuensi negatif dari situasi seperti itu, perlu (lebih lanjut saya akan menyimpang sedikit dari teks asli untuk menjelaskan proses lebih detail daripada di artikel - kira-kira Trans):
1) buat file script.js dengan konten berikut (dengan janji ekstra):
new Promise((resolve) => {
2) buka baris perintah (untuk pengguna Windows: untuk membuka baris perintah di folder dengan file yang diinginkan, tahan Shift, klik kanan, pilih "Buka jendela perintah"), jalankan script.js menggunakan perintah berikut (Node harus diinstal. js):
node --trace-events-enabled script.js
3) Node.js membuat file log (dalam kasus saya node_trace.1.txt) dalam folder dengan skrip;
4) buka Chrome (karena hanya berfungsi di dalamnya), masukkan "chrome: // tracing" di bilah alamat;
5) klik Muat, muat file log yang dibuat oleh Node.js;
6) buka tab Janji.
Kami melihat sesuatu seperti berikut:

Blok hijau adalah janji, yang masing-masing membutuhkan beberapa milidetik untuk diselesaikan. Oleh karena itu, semakin banyak janji akan, semakin lama mereka akan dilakukan.
Kami menulis ulang script.js:
new Promise((resolve, reject) => { const user = { name: 'John Doe', age: 50, } if(user.age > 25) { resolve() } else { reject('Age is less than 25') } }).then(() => { console.log('Age is greater than 25') }).catch(e => { console.log(e.message) })
Ulangi "jejak".
Kami melihat yang berikut:

Ada lebih sedikit blok hijau (janji), yang berarti bahwa waktu eksekusi kode telah berkurang.
Dengan demikian, Anda harus menggunakan beberapa janji hanya jika Anda perlu menjalankan beberapa kode asinkron.
Terima kasih atas perhatian anda Semoga akhir pekanmu menyenangkan! Saya akan senang dengan komentar apa pun.