Kami menguasai async / menunggu contoh nyata

Konstruksi async / await adalah pendekatan yang relatif baru untuk menulis kode asinkron dalam JavaScript. Itu didasarkan pada janji dan, sebagai hasilnya, tidak menghalangi aliran utama. Inovasi dari desain ini adalah karena itu, kode asinkron menjadi serupa dengan sinkron dan berperilaku dengan cara yang sama. Ini membuka peluang besar bagi programmer.

gambar

Sebelum munculnya async / menunggu, panggilan balik dan janji digunakan dalam pengembangan mekanisme program asinkron. Penulis materi, terjemahan yang kami terbitkan hari ini, menyarankan pertama-tama mengingat cara menulis kode dengan cara lama, dan kemudian, menggunakan contoh nyata, pelajari penggunaan async / tunggu.

Telepon balik


Berikut adalah contoh kode yang menggunakan panggilan balik (fungsi panggilan balik):

setTimeout(() => {  console.log('This runs after 1000 milliseconds.'); }, 1000); 

Saat menggunakan fungsi panggilan balik bersarang, ada masalah yang disebut neraka panggilan balik. Berikut ini adalah contoh kode yang disederhanakan untuk menggambarkan masalah ini:

 asyncCallOne(() => { asyncCallTwo(() => {   asyncCallThree(() => {     asyncCallFour(() => {       asyncCallFive(() => {         //         })     })   }) }) }) 

Jika kode berisi struktur yang terdiri dari panggilan balik yang bersarang satu sama lain, kode semacam itu mungkin sulit dipahami, akan sulit untuk dipelihara.

Janji


Berikut adalah contoh kode yang menggunakan janji (Objek janji):

 const promiseFunction = new Promise((resolve, reject) => { const add = (a, b) => a + b; resolve(add(2, 2)); }); promiseFunction.then((response) => { console.log(response); }).catch((error) => { console.log(error); }); 

Fungsi promiseFunction() fungsi promiseFunction() dari contoh ini mengembalikan objek Promise , yang merupakan tindakan tertentu yang dilakukan oleh fungsi. Panggilan ke metode resolve() menunjukkan janji bahwa operasinya selesai dengan sukses. Dalam konstruksi seperti itu, metode .then() dari janji-janji juga digunakan - dengan bantuannya, setelah berhasil menyelesaikan janji, Anda dapat melakukan panggilan balik tertentu. Metode .catch() dipanggil jika terjadi kesalahan selama pekerjaan janji.

Fungsi asinkron


Fungsi yang dideklarasikan menggunakan async (fungsi asinkron) memberi kami kesempatan untuk menulis kode yang rapi dan tidak kelebihan dengan konstruk layanan, yang memungkinkan kami mendapatkan hasil yang sama dengan yang kami peroleh menggunakan janji. Perlu dicatat bahwa async pada dasarnya hanya "gula sintaksis" untuk janji.

Fungsi asinkron dibuat menggunakan kata kunci async ketika mendeklarasikan suatu fungsi. Ini terlihat seperti ini:

 const asyncFunction = async () => { //  } 

Fungsi asinkron dapat dihentikan sementara menggunakan kata kunci await . Ini hanya dapat digunakan dalam fungsi asinkron. Ini memungkinkan Anda untuk mengembalikan hasil dari fungsi asinkron, yang akan tersedia setelah fungsi tersebut menyelesaikan pelaksanaan tugas.

Bandingkan operasi fungsi asinkron dan janji yang mengembalikan string:

 //   const asyncGreeting = async () => 'Greetings'; //  const promiseGreeting = () => new Promise(((resolve) => { resolve('Greetings'); })); asyncGreeting().then(result => console.log(result)); promiseGreeting().then(result => console.log(result)); 

Sangat mudah untuk melihat bahwa menggunakan async memungkinkan Anda untuk menulis kode asinkron yang terlihat seperti sinkron. Kode ini lebih mudah digunakan.

Sekarang kita telah membahas hal-hal dasar, mari kita beralih ke contoh kita.

Konverter mata uang


▍ Persiapan awal


Di sini kita akan membuat yang sederhana, tetapi kognitif dari sudut pandang mempelajari pembangunan aplikasi async / menunggu. Ini adalah konverter mata uang yang menggunakan data nyata yang diperoleh dari API yang sesuai. Program menerima jumlah dalam mata uang tertentu, kode mata uang ini, serta kode mata uang yang ingin kami konversi jumlah ini. Setelah itu, program menampilkan hasilnya dengan terlebih dahulu mengunduh data saat ini pada nilai tukar. Program ini juga menampilkan daftar negara tempat Anda dapat membelanjakan uang dalam mata uang yang jumlah transfernya ditentukan.

Secara khusus, di sini kita akan menggunakan data dari dua sumber informasi yang tidak sinkron:

  1. Layanan Currencylayer.com . Di situs ini Anda perlu membuat akun gratis dan mendapatkan kunci untuk mengakses API (Kunci Akses API). Dari sini kami akan mengambil data yang diperlukan untuk konversi jumlah dari satu mata uang ke mata uang lainnya.
  2. Layanan restcountries.eu . Ini dapat digunakan tanpa registrasi. Dari sini kami mengunggah data tempat Anda dapat menggunakan mata uang tempat kami mengonversi jumlah uang yang ditentukan.

Buat direktori baru dan jalankan perintah npm init di dalamnya. Ketika program menanyakan kepada kami pertanyaan tentang nama paket yang sedang dibuat, kami akan memperkenalkan currency-converter . Anda tidak dapat menjawab pertanyaan lain dari program dengan menekan Enter sebagai respons. Setelah itu, instal paket Axios di proyek kami dengan menjalankan npm install axios --save di direktori-nya. Buat file baru bernama currency-converter.js .

Mari kita mulai menulis kode program dengan menghubungkan Axios di file ini:

 const axios = require('axios'); 

Proyek kami akan memiliki tiga fungsi asinkron. Yang pertama akan memuat data mata uang. Yang kedua akan memuat data negara. Yang ketiga akan mengumpulkan data ini, menyajikannya dalam bentuk yang mudah digunakan dan menampilkannya di layar.

▍ Fungsi pertama adalah pemuatan data mata uang yang tidak sinkron


Mari kita membuat fungsi getExchangeRate() asynchronous yang akan mengambil dua argumen: fromCurrency dan toCurrency :

 const getExchangeRate = async (fromCurrency, toCurrency) => {} 

Dalam fungsi ini kita perlu memuat data. Dengan menggunakan async / menunggu konstruksi, Anda dapat menulis data yang diterima secara langsung ke variabel atau konstanta tertentu. Sebelum menulis kode untuk fungsi ini, jangan lupa untuk mendaftar di situs dan dapatkan kunci akses API. Untuk memuat data, kita membutuhkan konstruksi berikut:

 const response = await axios.get('http://www.apilayer.net/api/live?access_key=[    API]'); 

Setelah menerima respons sistem, data yang kita butuhkan dapat ditemukan di objek response.data.quotes di response.data.quotes . Berikut ini adalah fragmen objek dengan data yang menarik bagi kami (terlihat dalam program sebagai response.data ):

 {  "success":true,  "terms":"https:\/\/currencylayer.com\/terms",  "privacy":"https:\/\/currencylayer.com\/privacy",  "timestamp":1547891348,  "source":"USD",  "quotes":{     "USDAED":3.673042,     "USDAFN":75.350404,     "USDALL":109.203989, ...     "USDZWL":322.355011  } } 

Tempatkan objek dengan nilai tukar dalam rate konstan:

 const rate = response.data.quotes; 

Kode mata uang dasar dapat ditemukan di response.data.source . Kami menulis kode mata uang dasar dalam mata uang dasar konstan:

 const baseCurrency = response.data.source; 

Karena, secara default, data yang dikembalikan oleh API ini adalah nilai tukar terhadap dolar Amerika (USD), buat usd konstan di mana kami akan menulis hasil pembagian 1 dengan nilai tukar yang ditentukan jumlahnya:

 const usd = 1 / rate[`${baseCurrency}${fromCurrency}`]; 

Perhatikan bagaimana kunci terbentuk, yang menurutnya kita mendapatkan nilai dari kursus. Dalam objek yang diperoleh dari API, yang fragmennya diberikan di atas, kuncinya adalah string dimulai dengan USD dan berakhir dengan kode mata uang yang sesuai. Karena diasumsikan bahwa program kami menerima kode mata uang string, kami menghasilkan kunci dengan menggabungkan string yang berisi kode mata uang dasar dan apa yang diteruskan ke fungsi dalam parameter fromCurrency .

Sekarang, untuk mendapatkan nilai tukar dari fromCurrency ke toCurrence , kami mengalikan usd konstan dengan nilai untuk toCurrency . Ini terlihat seperti ini:

 const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`]; 

Sebagai hasilnya, kami akan mengembalikan apa yang masuk ke exchangeRate . Begini kode lengkapnya:

 const getExchangeRate = async (fromCurrency, toCurrency) => {   try {     const response = await axios.get('http://www.apilayer.net/api/live?access_key=[    API]');     const rate = response.data.quotes;     const baseCurrency = response.data.source;     const usd = 1 / rate[`${baseCurrency}${fromCurrency}`];     const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`];     return exchangeRate;   } catch (error) {     throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`);   } }; 

Harap perhatikan bahwa konstruksi coba / tangkap biasa digunakan untuk menangani kesalahan yang mungkin terjadi selama eksekusi permintaan.

▍ Fungsi kedua adalah memuat data negara secara tidak sinkron


Fungsi kedua kami, getCountries() , yang secara tidak sinkron memuat informasi tentang negara tempat Anda dapat menggunakan mata uang tempat kami akan mengonversi jumlah yang ditentukan dalam mata uang lain, akan menggunakan argumen currencyCode :

 const getCountries = async (currencyCode) => {} 

Untuk memuat data, kami menggunakan perintah berikut:

 const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`); 

Jika, misalnya, kami menggunakan kode HRK (Kroasia kuna) dalam permintaan, maka kami akan menerima kode JSON sebagai tanggapan, sebagiannya ditunjukkan di bawah ini:

 [   {     "name":"Croatia", ...  } ] 

Ini adalah berbagai objek dengan informasi tentang negara. Properti name benda-benda ini mengandung nama negara. Anda dapat mengakses larik ini menggunakan konstruk response.data . Kami menerapkan metode array map() untuk mengekstraksi nama negara dari data yang diterima dan mengembalikan data ini dari fungsi getCountries() , yang akan menjadi array nama negara:

 return response.data.map(country => country.name); 

Berikut adalah kode fungsi getCountries() lengkap:

 const getCountries = async (currencyCode) => {   try {     const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);     return response.data.map(country => country.name);   } catch (error) {     throw new Error(`Unable to get countries that use ${currencyCode}`);   } }; 

▍Fungsi ketiga - pengumpulan dan keluaran data


Fungsi asinkron ketiga kami, convertCurrency () , akan menerima argumen fromCurrency , toCurrency dan amount - kode dan jumlah mata uang.

 const convertCurrency = async (fromCurrency, toCurrency, amount) => {} 

Di dalamnya, kita pertama-tama mendapatkan nilai tukar:

 const exchangeRate = await getExchangeRate(fromCurrency, toCurrency); 

Lalu kami memuat daftar negara:

 const countries = await getCountries(toCurrency); 

Selanjutnya, kami melakukan konversi:

 const convertedAmount = (amount * exchangeRate).toFixed(2); 

Dan setelah semua data yang diperlukan dikumpulkan, kami mengembalikan garis yang akan dilihat pengguna program:

 return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`; 

Berikut adalah kode fungsi lengkap:

 const convertCurrency = async (fromCurrency, toCurrency, amount) => {   const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);   const countries = await getCountries(toCurrency);   const convertedAmount = (amount * exchangeRate).toFixed(2);   return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`; }; 

Harap perhatikan bahwa fungsi ini tidak memiliki blok coba / tangkap, karena hanya berfungsi dengan hasil yang diberikan kepadanya oleh dua fungsi yang dijelaskan sebelumnya.

▍ Mulai program


Kami telah menyiapkan tiga fungsi, dua di antaranya memuat data dari berbagai layanan, dan satu mengumpulkan data ini dan bersiap untuk keluaran. Sekarang kita hanya perlu memanggil fungsi ini, meneruskan semua yang kita butuhkan. Kami tidak akan menerapkan mekanisme di sini yang memungkinkan memanggil program kami dari baris perintah dengan mentransfer mata uang dan menjumlahkan kode ke sana, meskipun Anda dapat melakukan ini jika Anda mau. Kami hanya memanggil fungsi convertCurrency() , meneruskannya data yang diperlukan:

 convertCurrency('EUR', 'HRK', 20)   .then((message) => {     console.log(message);   }).catch((error) => {     console.log(error.message);   }); 

Di sini kami ingin mengetahui berapa banyak kuna Kroasia dapat ditukar dengan 20 euro dan sepanjang jalan untuk mencari tahu di negara mana uang ini dapat dihabiskan.

Kami memanggil program dengan memasukkan perintah berikut di terminal:

 node currency-converter.js 

Sebagai tanggapan, kami mendapatkan hal-hal berikut.


Hasil program

Di sini, untuk berjaga-jaga, kode lengkap proyek kami.

 const axios = require('axios'); const getExchangeRate = async (fromCurrency, toCurrency) => {   try {     const response = await axios.get('http://www.apilayer.net/api/live?access_key=[    API]');     const rate = response.data.quotes;     const baseCurrency = response.data.source;     const usd = 1 / rate[`${baseCurrency}${fromCurrency}`];     const exchangeRate = usd * rate[`${baseCurrency}${toCurrency}`];     return exchangeRate;   } catch (error) {     throw new Error(`Unable to get currency ${fromCurrency} and ${toCurrency}`);   } }; const getCountries = async (currencyCode) => {   try {     const response = await axios.get(`https://restcountries.eu/rest/v2/currency/${currencyCode}`);     return response.data.map(country => country.name);   } catch (error) {     throw new Error(`Unable to get countries that use ${currencyCode}`);   } }; const convertCurrency = async (fromCurrency, toCurrency, amount) => {   const exchangeRate = await getExchangeRate(fromCurrency, toCurrency);   const countries = await getCountries(toCurrency);   const convertedAmount = (amount * exchangeRate).toFixed(2);   return `${amount} ${fromCurrency} is worth ${convertedAmount} ${toCurrency}. You can spend these in the following countries: ${countries}`; }; convertCurrency('EUR', 'HRK', 20)   .then((message) => {     console.log(message);   }).catch((error) => {     console.log(error.message);   }); 

Ringkasan


Kami berharap contoh ini menggunakan async / menunggu konstruksi dalam kondisi nyata membantu mereka yang tidak memahami konstruksi ini sebelumnya untuk mengetahuinya.

Pembaca yang budiman! Jika Anda menggunakan async / menunggu konstruksi dalam praktik, silakan bagikan kesan Anda tentang itu.

Source: https://habr.com/ru/post/id436884/


All Articles