Apa kamu biasanya menggunakan async/await untuk memproses data dari atau ke API?
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.
Posting Komentar