Saya sedang menggali fitur node 7 async / await dan terus menemukan kode seperti ini
function getQuote() {
let quote = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
return quote;
}
async function main() {
try {
var quote = await getQuote();
console.log(quote);
} catch (error) {
console.error(error);
}
}
main();
Tampaknya ini satu-satunya kemungkinan menyelesaikan / menolak atau mengembalikan / melempar dengan async / await, namun, v8 tidak mengoptimalkan kode dalam blok coba / tangkap ?!
Apakah ada alternatif lain?
node.js
async-await
ecmascript-2017
Patrick
sumber
sumber
Jawaban:
Alternatif
Alternatif untuk ini:
akan menjadi seperti ini, menggunakan promise secara eksplisit:
atau sesuatu seperti ini, menggunakan gaya passing lanjutan:
Contoh asli
Apa yang dilakukan kode asli Anda adalah menangguhkan eksekusi dan menunggu janji dikembalikan
getQuote()
untuk diselesaikan. Kemudian melanjutkan eksekusi dan menulis nilai yang dikembalikan kevar quote
dan kemudian mencetaknya jika promise telah diselesaikan, atau melontarkan pengecualian dan menjalankan blok catch yang mencetak error jika promise tersebut ditolak.Anda dapat melakukan hal yang sama menggunakan Promise API secara langsung seperti pada contoh kedua.
Performa
Sekarang, untuk pertunjukannya. Mari kita uji!
Saya baru saja menulis kode ini -
f1()
memberikan1
nilai pengembalian,f2()
melempar1
sebagai pengecualian:Sekarang mari kita panggil kode yang sama jutaan kali, pertama dengan
f1()
:Dan kemudian mari beralih
f1()
kef2()
:Inilah hasil yang saya dapat
f1
:Inilah yang saya dapatkan untuk
f2
:Tampaknya Anda dapat melakukan sesuatu seperti 2 juta lemparan per detik dalam satu proses utas tunggal. Jika Anda melakukan lebih dari itu, Anda mungkin perlu mengkhawatirkannya.
Ringkasan
Saya tidak akan mengkhawatirkan hal-hal seperti itu di Node. Jika hal-hal seperti itu sering digunakan maka itu akan dioptimalkan pada akhirnya oleh tim V8 atau SpiderMonkey atau Chakra dan semua orang akan mengikutinya - ini tidak seperti itu tidak dioptimalkan sebagai prinsip, itu hanya bukan masalah.
Bahkan jika itu tidak dioptimalkan maka saya masih berpendapat bahwa jika Anda memaksimalkan CPU Anda di Node maka Anda mungkin harus menulis nomor Anda berderak di C - itulah tujuan dari add-on asli, antara lain. Atau mungkin hal-hal seperti node.native akan lebih cocok untuk pekerjaan itu daripada Node.js.
Saya bertanya-tanya apa yang akan menjadi kasus penggunaan yang perlu membuang begitu banyak pengecualian. Biasanya melempar pengecualian daripada mengembalikan nilai adalah pengecualian.
sumber
try catch
, bukan dari melempar pengecualian. Meskipun angkanya kecil, ini hampir 10 kali lebih lambat menurut pengujian Anda, dan itu tidak signifikan.Alternatif Serupa Dengan Penanganan Kesalahan Di Golang
Karena async / await menggunakan promise, Anda dapat menulis sedikit fungsi utilitas seperti ini:
Kemudian impor setiap kali Anda perlu menemukan beberapa kesalahan, dan bungkus fungsi async Anda yang mengembalikan sebuah janji dengannya.
sumber
Alternatif untuk blok try-catch adalah await-to-js lib. Saya sering menggunakannya. Sebagai contoh:
Sintaks ini jauh lebih bersih jika dibandingkan dengan try-catch.
sumber
Alternatifnya, alih-alih mendeklarasikan kemungkinan var untuk menahan kesalahan di atas, Anda dapat melakukannya
Meskipun itu tidak akan berhasil jika sesuatu seperti TypeError atau Reference error dilemparkan. Anda dapat memastikan itu adalah kesalahan biasa dengan
Preferensi saya untuk ini adalah membungkus semuanya dalam blok coba-tangkap besar di mana ada beberapa janji yang dibuat dapat membuatnya rumit untuk menangani kesalahan secara khusus pada janji yang membuatnya. Dengan alternatif menjadi beberapa blok coba-tangkap yang menurut saya sama-sama tidak praktis
sumber
Alternatif yang lebih bersih adalah sebagai berikut:
Karena fakta bahwa setiap fungsi asinkron secara teknis adalah sebuah janji
Anda dapat menambahkan tangkapan ke fungsi saat memanggilnya dengan await
Tidak perlu try catch, karena semua error promise ditangani, dan Anda tidak memiliki error kode, Anda dapat mengabaikannya di induk !!
Katakanlah Anda bekerja dengan mongodb, jika ada kesalahan Anda mungkin lebih suka menanganinya dalam fungsi yang memanggilnya daripada membuat pembungkus, atau menggunakan coba tangkap.
sumber
Saya ingin melakukan dengan cara ini :)
Ini mirip dengan menangani kesalahan dengan
co
sumber
await
!catch
Menurut pengalaman saya, cara ini berbahaya. Setiap kesalahan yang terjadi di seluruh tumpukan akan ditangkap, bukan hanya kesalahan dari janji ini (yang mungkin bukan yang Anda inginkan).Argumen kedua untuk suatu janji sudah merupakan panggilan balik penolakan / kegagalan. Lebih baik dan lebih aman untuk menggunakannya.
Berikut ini skrip ketikan satu baris yang saya tulis untuk menangani ini:
sumber