Saya telah membahas async
/ await
dan setelah mempelajari beberapa artikel, saya memutuskan untuk mengujinya sendiri. Namun, sepertinya saya tidak bisa memahami mengapa ini tidak berhasil:
async function main() {
var value = await Promise.resolve('Hey there');
console.log('inside: ' + value);
return value;
}
var text = main();
console.log('outside: ' + text);
Konsol menampilkan yang berikut (simpul v8.6.0):
> luar: [Janji objek]
> di dalam: Hei di sana
Mengapa pesan log di dalam fungsi dijalankan setelah itu? Saya pikir alasan async
/ await
diciptakan adalah untuk melakukan eksekusi sinkron menggunakan tugas asinkron.
Apakah ada cara saya bisa menggunakan nilai yang dikembalikan di dalam fungsi tanpa menggunakan .then()
after main()
?
await
tidak lain adalah gula untukthen
sintaksis janji .main
async/await
adalah bagian dari ES2017, bukan ES7 (ES2016)Jawaban:
Karena
main
mengembalikan janji; semuaasync
fungsi lakukan.Di tingkat atas, Anda harus:
Gunakan
async
fungsi tingkat atas yang tidak pernah menolak (kecuali jika Anda ingin kesalahan "penolakan ditangani"), atauGunakan
then
dancatch
, atau(Segera hadir!) Gunakan level-atas
await
, proposal yang telah mencapai Tahap 3 dalam proses yang memungkinkan penggunaan level-atasawait
dalam sebuah modul.# 1 -
async
Fungsi tingkat atas yang tidak pernah ditolakPerhatikan
catch
; Anda harus menangani penolakan janji / pengecualian async, karena tidak ada hal lain yang terjadi; Anda tidak memiliki penelepon untuk meneruskannya. Jika Anda mau, Anda bisa melakukan itu dengan memanggilnya melaluicatch
fungsi (bukantry
/catch
sintaks):... yang sedikit lebih ringkas (saya suka karena alasan itu).
Atau, tentu saja, jangan menangani kesalahan dan biarkan kesalahan "unhandled rejection".
# 2 -
then
dancatch
The
catch
handler akan dipanggil jika terjadi kesalahan dalam rantai atau di Andathen
handler. (Pastikancatch
pawang Anda tidak melakukan kesalahan, karena tidak ada yang terdaftar untuk menanganinya.)Atau keduanya argumen untuk
then
:Sekali lagi perhatikan kami mendaftarkan penangan penolakan. Tetapi dalam formulir ini, pastikan bahwa kedua
then
callback Anda tidak melakukan kesalahan, tidak ada yang terdaftar untuk menanganinya.Level 3 teratas
await
dalam modulKamu tidak bisa menggunakan
await
di tingkat atas skrip non-modul, tetapi proposal tingkat atasawait
( Tahap 3 ) memungkinkan Anda untuk menggunakannya di tingkat atas modul. Ini mirip dengan menggunakanasync
pembungkus fungsi tingkat atas (# 1 di atas) karena Anda tidak ingin kode tingkat atas Anda ditolak (melempar kesalahan) karena itu akan menghasilkan kesalahan penolakan yang tidak tertangani. Jadi, kecuali jika Anda ingin memiliki penolakan yang tidak ditangani ketika ada masalah, seperti dengan # 1, Anda ingin membungkus kode Anda dalam penangan kesalahan:Perhatikan bahwa jika Anda melakukan ini, modul apa pun yang mengimpor dari modul Anda akan menunggu sampai janji Anda
await
selesai; ketika sebuah modul yang menggunakan tingkat atasawait
dievaluasi, pada dasarnya ia mengembalikan janji kepada pemuat modul (seperti halnyaasync
fungsi), yang menunggu sampai janji itu diselesaikan sebelum mengevaluasi isi modul apa pun yang bergantung padanya.sumber
async
/await
yang sintaksis gula sekitar janji (baik jenis gula :-)). Anda tidak hanya menganggapnya sebagai mengembalikan janji; sebenarnya. ( Perincian .)async
opsi pertama. Untuk fungsi tingkat atas, saya bisa melihatnya dengan cara lain (kebanyakan karena dua tingkat lekukan padaasync
versi).await
proposal tingkat atas telah mencapai Tahap 3. :-)Tingkat Atas
await
telah pindah ke tahap 3, jadi jawaban untuk pertanyaan Anda Bagaimana saya bisa menggunakan async / menunggu di tingkat atas? adalah dengan hanya menambahkanawait
panggilan kemain()
:Atau hanya:
Perlu diingat bahwa itu masih hanya tersedia di [email protected] .
Jika Anda menggunakan TypeScript , itu mendarat di 3.8 .
v8 telah menambahkan dukungan dalam modul.
Ini juga didukung oleh Deno (seperti dikomentari oleh gonzalo-bahamondez).
sumber
Solusi aktual untuk masalah ini adalah dengan mendekatinya secara berbeda.
Mungkin tujuan Anda adalah semacam inisialisasi yang biasanya terjadi di tingkat atas aplikasi.
Solusinya adalah untuk memastikan bahwa hanya ada satu pernyataan JavaScript tunggal di tingkat atas aplikasi Anda. Jika Anda hanya memiliki satu pernyataan di bagian atas aplikasi Anda, maka Anda bebas untuk menggunakan async / menunggu di setiap titik lain di mana saja (tunduk pada aturan sintaksis yang normal)
Dengan kata lain, bungkus seluruh tingkat teratas Anda dalam suatu fungsi sehingga tidak lagi tingkat atas dan yang memecahkan pertanyaan tentang bagaimana menjalankan async / menunggu di tingkat atas aplikasi - Anda tidak.
Seperti inilah tampilan level teratas aplikasi Anda:
sumber
application()
menjadi async?Untuk memberikan info lebih lanjut di atas jawaban saat ini:
Isi
node.js
file saat ini digabungkan, dengan cara seperti string, untuk membentuk fungsi tubuh.Misalnya jika Anda memiliki file
test.js
:Kemudian
node.js
diam-diam akan menggabungkan fungsi yang terlihat seperti:Hal utama yang perlu diperhatikan, adalah bahwa fungsi yang dihasilkan BUKAN fungsi async. Jadi, Anda tidak dapat menggunakan istilah itu
await
langsung di dalamnya!Tetapi katakan Anda perlu bekerja dengan janji-janji di file ini, maka ada dua metode yang mungkin:
await
langsung di dalam fungsiawait
Opsi 1 mengharuskan kami untuk membuat ruang lingkup baru (dan ruang lingkup ini bisa
async
, karena kami memiliki kendali atas itu):Opsi 2 mengharuskan kita untuk menggunakan API janji berorientasi objek (paradigma yang kurang cantik namun fungsional untuk bekerja dengan janji)
Saya pribadi berharap bahwa, jika bisa diterapkan, node.js akan secara default menggabungkan kode menjadi suatu
async
fungsi. Itu akan menghilangkan sakit kepala ini.sumber
Menunggu level atas adalah fitur standar EcmaScript yang akan datang. Saat ini, Anda dapat mulai menggunakannya dengan TypeScript 3.8 (dalam versi RC saat ini).
Cara Memasang TypeScript 3.8
Anda dapat mulai menggunakan TypeScript 3.8 dengan menginstalnya dari npm menggunakan perintah berikut:
Pada saat ini, Anda perlu menambahkan
rc
tag untuk menginstal naskah versi 3.8 terbaru.sumber
Karena
main()
berjalan secara tidak sinkron, ia mengembalikan janji. Anda harus mendapatkan hasilnya dalamthen()
metode. Dan karenathen()
mengembalikan janji juga, Anda harus meneleponprocess.exit()
untuk mengakhiri program.sumber
exit()
memberi sinyal apakah terjadi kesalahan.process.exit(1)