Apa kamu biasanya menggunakan async/await untuk memproses data dari atau ke API?
Daftar Isi
Mempercepat async/await dengan Promise
Jika iya, kemungkinan besar kamu harus melakukannya secara paralel atau bergantian, yang sebenarnya oke-oke saja. Namun, ada cara untuk mempercepatnya, yaitu menggunakan Promise.
Seperti saat memperbarui 50+ data sekaligus, ini bisa memakan waktu hingga 50 detik dan akan mengganggu proses lainnya. Pengguna bingung selama menunggu dan sering meninggalkan halaman lebih cepat. Disini kamu sudah tahu masalah-masalahnya kan?.
Kalau belum, coba perhatikan kode berikut:
for (const record of records) {
await update(record);
}
Disitu coba kalian perkirakan berapa lama prosesnya jika ada 50 records dan setiap record akan memakan waktu sekitar 0.2 detik.
Dengan contoh di atas, maka total proses akan memakan waktu setidaknya 10 detik. Itu proses yang cukup lama untuk sebuah script. Terus, bagaimana caranya untuk mempercepatnya?
Perhatikan lagi contoh berikut yang menggunakan Promise.all/Promise.allSettled
const allPromises = [];
for (const record of records) {
const promise = update(record);
allPromises.push(promise);
};
await Promise.allSettled(allPromises);
Tidak seperti contoh sebelumnya yang menunggu satu proses selesai dan memproses data selanjutnya, sekarang setiap proses akan dijalankan bersamaan. Visualisasinya seperti berikut:
Terus untuk menerima hasil dari Promise bagaimana?
Menerima hasil data dari Promise.all/Promise.allSettled
Tidak semua promise akan berhasil, dan kadang kala beberapa akan gagal. Jika itu terjadi, bagaimana cara mengetahuinya?
Tenang, dengan array promise itu, kalian akan mendapatkan data kira-kira seperti berikut:
const values = await Promise.allSettled([
Promise.resolve(33),
Promise.reject(new Error('an error'))
])
console.log(values)
// [
// {status: "fulfilled", value: 33},
// {status: "rejected", reason: Error: an error}
// ]
Bisa kalian lihat, kita akan dapat object dengan isi status dan value jika berhasil, atau reason jika gagal.
Status disitu menunjukkan apakah promisenya itu sukses (Fulfilled) atau gagal (Rejected). Kembali ke contoh awal, dimana kita update record database, dan kita mau tau apakah updatenya berhasil atau tidak. Jadi hasil yang kita dapat kira-kira seperti berikut:
const allPromises = [];
for (const record of records) {
const promise = new Promise((resolve, reject) => {
update(t)
.then(() => { resolve(record.id) }); # berhasil
.catch(() => { reject(record.id) }); # gagal
});
allPromises.push(promise);
};
const outcomes = await Promise.allSettled(allPromises);
const succeeded = outcomes.filter(o => o.status === "fulfilled");
const succeededIds = succeeded.map(s => s.value);
const failed = outcomes.filter(o => o.status === "rejected");
const failedIds = failed.map(f => f.reason);
Atau bisa kalian lihat visualisasinya dibawah ini:
Array yang dikembalikan memberi tahu kita mana yang berhasil dan mana yang gagal.
Dan dengan gitu doang, kita dapat mengurangi operasi pengeditan massal 50+ records dari 10 detik menjadi kurang dari 5 detik dengan perubahan ini.
Perbedaan Promise.all dan Promise.allSettled
Perbedaan mendasar dari all dan allSettled terletak pada hasil yang akan kita dapatkan. Jika kita menggunakan all maka kita hanya akan menerima hasilnya jika semua promise berhasil atau resolved. Dan juga jika menggunakan all dan ada satu promise yang gagal, proses akan langsung dimatikan, dan langsung mengembalikan hasilnya.
Sedangkan allSettled akan menunggu semua promise dan tidak akan berhenti walaupun ada yang gagal. Jadi, jika kalian ingin memastikan semuanya berhasil sebelum masuk ke proses selanjutnya, kalian bisa gunakan all, dan jika kalian ingin tahu masing-masing promise, maka allSettled akan lebih baik.
Penutup
Begitulah penggunaan async/await dengan Promise. Jika ada pertanyaan atau hal-hal yang salah didalam artikel ini, kalian bisa kirimkan saran di kolom komentar.