Cara menggunakan PROMOSI di JavaScript

JavaScript adalah bahasa pemrograman yang ditafsirkan yang dikenal dengan gaya asinkronnya. Ini adalah salah satu faktor yang membuat JavaScript termasuk bahasa dengan kinerja cepat, bahkan tercepat jika dibandingkan dengan bahasa interpretasi lainnya, seperti Perl, PHP, Python, Ruby, dll (Ingat, ini bukan masalah bahasa yang dikompilasi. )

Pengertian asynchronus merupakan salah satu hal penting dalam dunia Javascript. Konsep ini sering terabaikan saat masih dalam tahap belajar dasar, mungkin karena konsepnya terlalu rumit untuk dijelaskan atau karena alasan lain. Bahkan banyak yang sudah bertahun-tahun menggunakan javascript, ternyata masih banyak yang masih belum paham dengan konsep asinkron. Meskipun dalam praktiknya mungkin sudah sering digunakan

Konsep asinkron memang merupakan salah satu konsep fundamental, namun tidak terlalu mudah untuk dipahami, namun ada istilah “practice makes perfect”. Semakin sering Anda berlatih, semakin baik pemahaman Anda. Tapi berlatih tanpa memahami konsep juga buta, terlalu banyak trial and error dan memakan waktu. Menurut saya, cara ideal untuk memahami asinkron adalah dengan memahami konsep secara bertahap dan mempraktekkannya. Ingat kuncinya bertahap bukan borongan

Catatan. Sebelum membaca artikel tentang Promise ini, setidaknya Anda harus memahami sedikit tentang asynchronous dan callback. Karena artikel ini pada dasarnya membahas materi fundamental lanjutan. Ada baiknya anda membaca terlebih dahulu artikel yang membahas kedua materi yang saya sebutkan di atas. baik?

Karena blog ini lumayan panjang, estimasi bacanya sampai 20 menit 😄. Jadi saya membuat daftar isi untuk memudahkan perpindahan bagian. Disarankan untuk menyiapkan camilan dan secangkir kopi agar Anda lebih menikmati bacaan ini

Mengetahui Janji

Janji adalah salah satu konsep yang hadir di ES6 (ES2015). Konsep ini hadir untuk mengubah gaya dalam memecahkan masalah proses asinkron yang sebelumnya bertele-tele. Sebelumnya kita menggunakan callback untuk menangani proses asinkron, namun lama kelamaan kita akan kesulitan ketika jumlah callback yang digunakan bertambah, bahkan akan ada callback di dalam callback dan seterusnya. Masalah ini sering disebut callback hell. Berikut adalah contoh panggilan balik neraka. (Asumsikan kita ingin membaca 4 file, kemudian ingin menggabungkan isi file tersebut menjadi 1 file)

fs.readFile('content1.txt', 'utf-8', (err, content1) => { if (err) throw err fs.readFile('content2.txt', 'utf-8', (err, content2) => { if (err) throw err fs.readFile('content3.txt', 'utf-8', (err, content3) => { if (err) throw err fs.readFile('content4.txt', 'utf-8', (err, content4) => { if (err) throw err fs.writeFile('result.txt', content1 + content2 + content3 + content4, err => { if (err) throw err console.log('Writing done!') }) }) }) }) })

Mata kita sakit saat melihat kode di atas kan? . Kode di atas sangat tidak dapat dipertahankan. Itu baru 5 callback, bagaimana kalau lebih?

Konsep dasar janji

Sebelum kita membahas lebih dalam tentang promise, ada baiknya kita memahami konsepnya terlebih dahulu agar tidak bingung. Dengan konsep Promise, secara manusiawi kita bisa membuat analogi sederhana seperti ini

Kami membuat janji dengan seorang teman untuk nongkrong di kafe besok malam

Kemudian kita dapat mengambil aspek-aspek penting dari janji itu, dan menyusun rencana seperti ini

  1. Batas waktu. besok malam
  2. Rencana. Nongkrong di kafe

Dari susunan tersebut, kemudian muncul pertanyaan

  1. Apa yang harus kami lakukan jika penunjukan telah mencapai tenggat waktu dan tidak berjalan sesuai rencana?
  2. Apa yang harus kita lakukan lagi jika janji telah mencapai batas waktu dan berjalan sesuai rencana atau tidak sesuai rencana?

Ya, namanya juga masa depan, tidak ada yang tahu kejadian yang akan menghalangi rencana tersebut. Mari kita asumsikan jika besok malam hujan dan badai, itu berarti kita hanya akan bertemu di pertandingan dengan teman-teman. Jadi, kami mendapatkan rencana akhir seperti ini

  1. Batas waktu. besok malam
  2. Rencana Utama. Nongkrong di kafe
  3. Rencana Lain. Mabar online
  4. Setelah itu. tidur

Nah, sekarang kita bisa membagi susunan rencana akhir menjadi 4 keadaan.

  1. Tertunda (Janji masih dalam proses di bawah batas waktu dan belum diketahui hasilnya)
  2. Terpenuhi
  3. Ditolak (Gagal, janji terpenuhi tapi ada kecelakaan yang terjadi sebelum atau mencapai batas waktu)
  4. Settled (Terselesaikan, artinya janji akan memasuki keadaan ini jika sudah dilaksanakan atau mencapai batas waktu, berhasil atau gagal)

Jadi, berikut ini adalah state dari alur Promise yang sebenarnya ada di JavaScript

Janji menyatakan

Jika diterjemahkan ke dalam koding, kita dapat menyimpulkan aspek-aspek penataan artikel seperti ini

  1. Besok malam adalah proses yang akan berjalan berdasarkan waktu
  2. Nongkrong di kafe adalah rencana utama kami jika besok malam berjalan sesuai keinginan (tidak ada kecelakaan yang menghalangi)
  3. Mabar adalah rencana lain jika rencana utama kita tidak tercapai (ada kecelakaan yang menghalangi)
  4. Tidur adalah rencana kami setelah nongkrong di kafe atau mabar

Kemudian kode seperti ini

besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) _

Jadi penjelasan dari coding diatas adalah jika janji besokMalam() berjalan sesuai rencana, maka kita akan nongkrongDiKafe. Jika ada kecelakaan (hujan/badai) yang terjadi di tengah-tengah besokMalam() janji maka kami akan besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 1. Nah, ketika nongkrongDiKafe atau besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 1 selesai maka yang terakhir kita akan besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 4

Seperti di dunia nyata, di dunia pemrograman kita juga harus merencanakan dan mengidentifikasi kemungkinan-kemungkinan yang akan terjadi pada aplikasi kita. Kemudian aplikasi kita berjalan dengan sempurna. Pernahkah Anda menggunakan aplikasi yang tiba-tiba macet, tertunda, tidak berfungsi, ditutup paksa, atau menampilkan pesan kesalahan yang tidak jelas? . Jadi seperti, aplikasi yang dibuat tidak tahu apa yang harus dilakukan ketika terjadi kejadian yang tidak direncanakan

Janji dalam praktek

Oke kita sudah membahas konsep dasar dari promise, setidaknya kita sudah mengerti bagaimana promise bekerja, keadaan apa yang terjadi pada promise dengan analogi yang saya jelaskan di atas. Dan di bagian ini kita akan melakukan latihan dasar

Buat objek janji

Pada bagian sebelumnya, kita telah melihat contoh penggunaan promise dengan besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 5, besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 6 dan besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 7. Nah masalahnya, tidak semua fungsi yang kita gunakan ada di dalam objek Promise. Fungsi besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) _8 pada contoh callback hell di atas sebenarnya bukan merupakan objek promise, jika kita menggunakan besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 9 tentu akan menghasilkan error. Lalu, bagaimana cara membuat objek Promise dan menghilangkan panggilan balik yang kotor?

const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) })

Nah itulah cara membuat objek janji pada proses asinkron non-janji. Jadi, apa itu const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) }) _0 dan const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) }) 1? . ) Kemudian kita bisa menggunakan janji yang telah kita buat seperti ini

Oya, dalam hal itu hanya seperti blok try-catch dong, seperti pada bahasa pemrograman pada umumnya. Tunggu gan, try-catch untuk proses sinkron, sedangkan promise untuk proses asinkron. Mari kita coba ubah ini

Tebak mana yang muncul lebih dulu? . Yang muncul pertama adalah const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) }) 4. Karena apa? . Bedanya jika kita menggunakan proses sinkron seperti yang biasa kita gunakan, maka proses dibawahnya akan dibuat menunggu sampai proses diatasnya selesai

Rantai janji

Sebelumnya kita sudah membahas callback hell dan melihat contoh pembuatan & penggunaan promise. Nah, pada kasus callbach hell di atas sebenarnya kita bisa mengubahnya menjadi sebuah promise agar kodenya lebih rapi dan mudah dibaca. Mari mencoba

Pertama-tama, kita mengubah fungsi const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) }) _6 dan const readFile = (file, options) => new Promise((fulfill, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return fulfill(content) }) }) 7 menjadi promise terlebih dahulu, seperti ini

const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) })

Tunggu dulu, tapi kenapa cara membuat objek promise berbeda dengan contoh yang sudah dibuat?

Nah ini adalah contoh baru dimana kita menggunakan teknik currying, di blog sebelumnya saya sudah menjelaskan tentang currying, bisa dibaca disini. Oke skip aja, kita lanjut dulu. Nah, setelah membuat objek promise seperti di atas, mari kita gunakan promise untuk menyelesaikan kasus seperti callback hell tadi

const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err })

Bagaimana? . Ya walaupun masih bisa dibuat sederhana. Oke, mari kita lanjutkan

Janji dengan praktik terbaik

Berbicara tentang best practice, sangat tabu bagi seorang software engineer untuk membiarkan kode aslinya apa adanya, yang penting caranya atau sejenisnya. Sayangnya, aplikasi akan "berukuran besar dan berat karena banyaknya library atau node_modules yang diinstal"

Seorang insinyur perangkat lunak yang baik pasti akan memprioritaskan semua fitur bawaan terlebih dahulu daripada harus terburu-buru menggunakan perpustakaan atau aplikasi pihak ketiga, dan memikirkan cara membuat kode lebih mudah dibaca dan optimal dalam hal kinerja dan algoritme, serta dapat digunakan dalam jangka panjang. Nah, lebih dari itu, pada poin ini kita akan membahas apa yang bisa membuat kode promise lebih mudah dibaca dan dioptimalkan?

Asinkron - Menunggu

Jika Anda masih bingung atau belum familiar dengan promise, const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) 0 adalah cara yang tepat untuk membuat kode promise lebih mudah dibaca dan mudah dibaca seperti kode sinkron pada umumnya. Tapi ketentuannya keyword const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) 1 harus di fungsi const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) 2. Misalnya, kami menggunakan kasus const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) 3 seperti di atas

async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') })

Seperti yang bisa kita lihat, kode di atas sangat mudah dibaca seperti proses sinkron pada umumnya. Kita dapat menggunakan blok const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) _4 seperti biasa untuk menangani kesalahan. Tapi, kenapa di const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) _5 masih ada besokMalam() .then(nongkrongDiKafe) .catch(mabar) .finally(tidur) 5? . Dan memang ini praktik terbaik, kita harus mengembalikan janji pada fungsi async. Mari kita lihat contoh penggunaan fungsi async yang bukan praktik terbaik

Apa? . Jadi, meskipun kita sudah langsung mengembalikan nilai di fungsi async, kita tetap harus memanggilnya seperti ini

Yup, ujungnya tetap kembali ke janji kan? . Jangan berharap Anda bisa mendapatkan nilai secara instan jika Anda mengembalikan nilai atau nilai dalam fungsi async. Adapun contoh best practice adalah

Jadi, jika Anda masih berpikir bahwa async-wait dan promise adalah hal yang berbeda, Anda salah. Karena sudah dijelaskan diatas bahwa const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) 0 sendiri merupakan cara atau teknik membuat promise code mudah dibaca seperti synchronous code pada umumnya. Kemudian, kesimpulannya adalah

Nilai dari fungsi async akan selalu berisi Janji meskipun yang kita kembalikan adalah nilai yang bukan Janji. Jadi, ________22______0

Karena jika Anda mau, fungsi async bukanlah fungsi normal yang dapat langsung mengembalikan nilai atau nilai, melainkan akan tetap berjalan secara asinkron dan akan "memaksa" mengembalikan Promise

Nanti kalau sering ketemu kasusnya dan sering baca teorinya pasti paham sendiri ^^

Menjanjikan kekuatan super

Sebenarnya ada banyak fitur pada objek promise, namun sangat sedikit orang yang melihat dan menggunakannya, padahal fitur tersebut merupakan kekuatan super dan membantu dalam menyelesaikan kasus promise, terutama untuk penanganan array promise. Fitur yang dimaksud adalah

  1. Janji. balapan
  2. Janji. semua
  3. Janji. allSettled (Rilis baru, ES2020)
  4. Janji. ada (masih dalam proposal)

Nah, kita akan bahas satu per satu fitur tersebut beserta studi kasusnya. Namun, karena const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _1 belum dirilis, kami hanya akan membahasnya sampai const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 2

1. Janji. balapan

const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _3 adalah salah satu fitur dari janji yang menghasilkan janji pertama yang memasuki keadaan terpenuhi dari susunan janji. Ketentuannya adalah sebagai berikut

  1. const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 3 akan memasuki kondisi terpenuhi jika salah satu janji dari array janji memasuki kondisi terpenuhi terlebih dahulu (Hasil pengembalian menghasilkan nilai dari janji terpenuhi pertama). Intinya balapan itu kaya, siapa yang menang diakui, janji setelah itu akan diabaikan
  2. const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 3 akan melakukan hubungan pendek atau memasuki kondisi ditolak jika salah satu janji memasuki kondisi ditolak terlebih dahulu

Lalu, apa studi kasusnya jika Anda ingin menerapkan const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 3 ini? . Nah untuk kasus seperti ini

Kami ingin membuat batas waktu pada permintaan aplikasi kami agar pengguna tidak menunggu lama untuk hal yang tidak pasti dan segera mengambil tindakan. (ya namanya juga janji, yang jelas belum pasti. tertawa terbahak-bahak)

Nah kira-kira implementasi kodenya seperti ini

Ada kasus menarik lainnya yang saya implementasikan menggunakan const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 3 ini, yaitu membuat sistem pembatalan permintaan. Untuk kasus ini

Kami ingin membuat pencarian langsung yang langsung meminta data ke server saat pengguna mengetik kata kunci di formulir. Namun permasalahannya adalah ketika user terus mengetik maka setiap perubahan dari kata kunci yang diketik akan di request ke server, jika user terus mengetik maka proses request bertambah, hal ini juga membuat aplikasi menjadi berat. Jadi disini tugas kita adalah membuat sistem yang akan membatalkan request sebelumnya ketika user masih mengetik dan request yang berjalan hanya kata kunci terakhir dari user yang mengetik

Contoh penerapannya adalah sebagai berikut

const HttpRequest = (requestInit = {}) => ({ cancel: () => false, make(url) { const cancelToken = new Promise((_, reject) => { this.cancel = () => reject({ cancelled: true }) }) return Promise.race([cancelToken, fetch(url, requestInit)]) } }) const request = HttpRequest({ method: 'GET', headers: { 'Content-Type': 'application/json' }, }) const search = event => { const keyword = event.target.value console.log(`Searching for ${keyword}..`) request.cancel() request.make(`//api.github.com/search/users?q=${keyword}`) .then(response => response.json()) .then(result => { console.log(result) }) .catch(err => { if (!err.cancelled) { console.log('an error occured', err) } }) } document.getElementById('form-search') .addEventListener('input', search)

Nah kira-kira seperti itulah contoh penerapan const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 3 untuk membuat sistem request cancel. Omong-omong, ini tidak hanya berlaku untuk kasus pencarian langsung, tetapi kami juga dapat menerapkannya pada tombol batal di formulir input. Jadi pengguna dapat mengklik batal seperti itu saat mengirimkan. Keren juga kan?

2. Janji. semua

async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) _0 adalah fitur janji yang menghasilkan nilai dari semua janji yang dipenuhi diproses. Ketentuannya adalah sebagai berikut

  1. async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) _0 akan memasuki status terpenuhi jika semua janji dari array janji memasuki status terpenuhi (Hasil pengembalian menghasilkan array nilai janji-janji yang terpenuhi). Tidak seperti const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _3, async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 akan menunggu janji-janji lain yang masih tertunda hingga semuanya memasuki status terpenuhi
  2. async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 akan melakukan hubungan pendek atau memasuki keadaan ditolak jika salah satu janji memasuki keadaan ditolak. (Jadi, jika hanya salah satu dari janji-janji dari async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 memasuki keadaan ditolak, itu akan menggagalkan semua janji-janji yang masih tertunda atau sudah dipenuhi)

Lalu, apa studi kasus untuk menerapkan async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 ini? . Intinya fitur ini bagus digunakan ketika kita dihadapkan pada beberapa promise yang tidak saling ketergantungan, namun kita ingin mendapatkan hasil dari promise tersebut sekaligus. Sebagai contoh jangan terlalu jauh, langsung saja kita gunakan contoh kasus dari poin async-wait di atas

Sebelumnya, kami menulis kode async-await di atas seperti ini

Jadi, kami memodifikasi fungsi seperti ini untuk mendapatkan kinerja yang lebih optimal

async function mergeContent() { const read = readFile('utf-8') try { const result = await Promise.all([ read('content1.txt'), read('content2.txt'), read('content3.txt'), read('content4.txt') ]) await writeFile('result.txt', result.join('')) } catch (err) { throw err } return read('result.txt') }

Mengapa saya mengatakan bahwa kinerjanya lebih optimal saat menggunakan async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0?

  1. async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 8 kami menyebutnya p1 yang membutuhkan waktu 1000ms
  2. async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) _9 kami menyebutnya p2 yang membutuhkan waktu 400ms
  3. const HttpRequest = (requestInit = {}) => ({ cancel: () => false, make(url) { const cancelToken = new Promise((_, reject) => { this.cancel = () => reject({ cancelled: true }) }) return Promise.race([cancelToken, fetch(url, requestInit)]) } }) const request = HttpRequest({ method: 'GET', headers: { 'Content-Type': 'application/json' }, }) const search = event => { const keyword = event.target.value console.log(`Searching for ${keyword}..`) request.cancel() request.make(`//api.github.com/search/users?q=${keyword}`) .then(response => response.json()) .then(result => { console.log(result) }) .catch(err => { if (!err.cancelled) { console.log('an error occured', err) } }) } document.getElementById('form-search') .addEventListener('input', search) 0 kita sebut sebagai p3 yang membutuhkan waktu 100ms
  4. const HttpRequest = (requestInit = {}) => ({ cancel: () => false, make(url) { const cancelToken = new Promise((_, reject) => { this.cancel = () => reject({ cancelled: true }) }) return Promise.race([cancelToken, fetch(url, requestInit)]) } }) const request = HttpRequest({ method: 'GET', headers: { 'Content-Type': 'application/json' }, }) const search = event => { const keyword = event.target.value console.log(`Searching for ${keyword}..`) request.cancel() request.make(`//api.github.com/search/users?q=${keyword}`) .then(response => response.json()) .then(result => { console.log(result) }) .catch(err => { if (!err.cancelled) { console.log('an error occured', err) } }) } document.getElementById('form-search') .addEventListener('input', search) 1 kita sebut sebagai p4 yang membutuhkan waktu 1500ms

Nah, jika kita menggunakan 4 kali menunggu secara berurutan tadi, berarti kita telah menghabiskan waktu untuk menunggu hal-hal yang tidak penting. Mengapa?

Jadi, mengapa menunggu? . Mengapa? . Begitu juga dengan p4, kita juga harus menunggu p3 selesai. Belum lagi const fs = require('fs') const readFile = options => file => new Promise((resolve, reject) => { fs.readFile(file, options, (err, content) => { if (err) return reject(err) return resolve(content) }) }) const writeFile = (file, content) => new Promise((resolve, reject) => { fs.writeFile(file, content, err => { if (err) return reject(err) return resolve() }) }) _7, hadeeh

Jadi, 1000ms + 400ms + 100ms + 1500ms = 3000ms (3 detik. )

Tapi, jika kita menggunakan async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0, keempat proses tersebut tidak saling menunggu, melainkan berjalan secara bersamaan. Namun jika satu proses selesai, maka proses tersebut menunggu proses lainnya selesai. Jika berdasarkan asumsi di atas, maka

Keempat proses berjalan secara bersamaan, tetapi p3 selesai terlebih dahulu, diikuti oleh p2 kemudian p1 dan akhirnya p4. Jadi waktu yang digunakan untuk menjalankan keempat proses tersebut merupakan waktu yang paling lama dari keempat proses tersebut, yaitu. p4 = 1500ms (1. 5 detik. )

Kalau masih bingung, mari kita lihat contoh perbandingan pada grafik ini

Perbandingan waktu muat Async & Sinkronisasi

Nah, sampai sekarang kamu paham kan? . Ya walaupun selisihnya hanya 1,5 detik itu kan hanya 4 proses, bagaimana jika prosesnya lebih? . Oleh karena itu, kita harus tahu kapan dan di mana menggunakan async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 atau memang harus menunggu proses berjalan satu per satu

3. Janji. allSettled

const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _2 ini merupakan fitur baru di ES2020, fitur ini hadir untuk mengatasi kekurangan dari async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0. Semua janji pada async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) _0 akan ditolak jika hanya salah satu janji yang masuk ke status ditolak. Tapi tidak dengan const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _2, const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 2 ini tidak memiliki status ditolak kecuali kita membuatnya sendiri. Agar tidak bingung, berikut ketentuan const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 2

  1. const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) _2 akan memasuki keadaan terpenuhi jika semua janji yang masih tertunda memasuki keadaan diselesaikan, terlepas dari dipenuhi atau ditolak. (Hasil yang dikembalikan adalah larik objek yang berisi status dan nilai dari janji yang akan diselesaikan. Jika terpenuhi maka akan ada nilai kunci, namun jika ditolak maka akan ada kunci alasan yang berisi alasan mengapa gagal)
  2. const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 2 tidak ada status hubung singkat atau status ditolak seperti janji lainnya

Lalu, apa implementasi untuk ________22______2 ini? . Untuk kasus dan penggunaannya sama dengan async function mergeContent() { const read = readFile('utf-8') try { const content1 = await read('content1.txt') const content2 = await read('content2.txt') const content3 = await read('content3.txt') const content4 = await read('content4.txt') return writeFile('result.txt', content1 + content2 + content3 + content4) } catch (err) { throw err } } mergeContent() .then(() => { console.log('Writing done!') }) 0 tetapi jika kita tidak ingin membatalkan semuanya hanya karena satu janji yang gagal, const read = readFile('utf-8'), result = '' read('content1.txt') .then(content1 => { result += content1 return read('content2.txt') }) .then(content2 => { result += content2 return read('content3.txt') }) .then(content3 => { result += content3 return read('content4.txt') }) .then(content4 => { result += content4 return writeFile('result.txt', result) }) .then(() => { console.log('writing done!') }) .catch(err => { throw err }) 2 adalah solusinya

Sebagai contoh, mungkin pernah kita jumpai kasus untuk membaca file yang path filenya dari array atau database, daripada mengecek satu per satu lalu membacanya, lebih baik dibaca saja, kalaupun ada error, itu akan dilewati. Cuplikan kode terlihat seperti ini

Nah, bagus banget kan?

Penutupan

Oke, mungkin kali ini kita bahas Janji kita saja. Jadi bisa disimpulkan kan? . Semua fitur bawaan dari promise sangat membantu untuk menyelesaikan masalah dan kasus asinkron. Jika cara kita benar dalam mengimplementasikan janji, itu sangat bagus, karena sangat jarang orang memperhatikan hal ini. Yupp ya, satu hal lagi mungkin karena kebanyakan orang benci asynchronous programming, ini buktinya

NodeJS

Seperti yang dapat dilihat di atas, banyak orang membenci, tidak menyukai NodeJS, atau menganggap NodeJS sulit karena menurut mereka pemrograman asinkron "sangat sulit dilakukan dengan benar". Ya susah banget kalo belum tau konsepnya haha, jadi semoga dengan membaca blog ini kalian paham konsep asynchronous programming khususnya Promise di NodeJS. Semoga bermanfaat, jangan lupa share ya 😃

Apa itu Janji dalam javascript?

Janji adalah salah satu fitur penting ES6. Object promise merepresentasikan solusi atau error pada operasi Asinkron.

Kapan kita menggunakan asinkron?

Proses asinkron sering digunakan untuk komunikasi data , karena data adalah bagian inti dari aplikasi, konsep asinkron sangat penting untuk memahami.

Apa itu fungsi callback javascript?

Callback dalam Javascript adalah fungsi yang dikirim sebagai parameter ke fungsi lain. Fungsi di atas adalah contoh callback yang berjalan sinkron karena callback fungsi langsung dieksekusi pada proses fungsional yang bersifat sinkron.

Apa itu async Tunggu Javascript?

Async/await adalah fitur yang hadir sejak ES2017. Fitur ini memudahkan kita menangani proses asinkron . Async/Await adalah sintaks khusus yang digunakan untuk menangani Janji sehingga penulisan kode lebih efisien dan rapi.

Postingan terbaru

LIHAT SEMUA