Ya, Janji adalah panggilan balik yang tidak sinkron. Mereka tidak dapat melakukan apa pun yang tidak bisa dilakukan panggilan balik, dan Anda menghadapi masalah yang sama dengan asinkron seperti halnya dengan panggilan balik biasa.
Namun, Janji lebih dari sekadar panggilan balik. Mereka adalah abstraksi yang sangat perkasa, memungkinkan kode fungsional lebih bersih dan lebih baik dengan boilerplate yang lebih rentan kesalahan.
Jadi apa ide utamanya?
Janji adalah objek yang mewakili hasil perhitungan tunggal (tidak sinkron). Mereka menyelesaikan hasil itu hanya sekali. Ada beberapa hal yang artinya:
Janji menerapkan pola pengamat:
- Anda tidak perlu tahu panggilan balik yang akan menggunakan nilai sebelum tugas selesai.
- Alih-alih mengharapkan panggilan balik sebagai argumen untuk fungsi Anda, Anda dapat dengan mudah
return
menjadi objek Janji
- Janji itu akan menyimpan nilai, dan Anda bisa transparan menambahkan panggilan balik kapan pun Anda mau. Ini akan dipanggil ketika hasilnya tersedia. "Transparansi" menyiratkan bahwa ketika Anda memiliki janji dan menambahkan panggilan balik ke dalamnya, itu tidak membuat perbedaan pada kode Anda apakah hasilnya telah tiba - API dan kontraknya sama, menyederhanakan banyak caching / memoisasi.
- Anda dapat menambahkan beberapa panggilan balik dengan mudah
Janji-janji tidak dapat ditagih ( monadik , jika Anda mau ):
- Jika Anda perlu mengubah nilai yang diwakili oleh janji, Anda memetakan fungsi transformasi atas janji dan mendapatkan kembali janji baru yang mewakili hasil yang diubah. Anda tidak dapat secara sinkron mendapatkan nilai untuk menggunakannya, tetapi Anda bisa dengan mudah mengangkat transformasi dalam konteks janji. Tidak ada panggilan balik boilerplate.
- Jika Anda ingin membuat dua tugas asinkron, Anda dapat menggunakan
.then()
metode ini. Dibutuhkan panggilan balik untuk dipanggil dengan hasil pertama, dan mengembalikan janji untuk hasil janji bahwa panggilan balik kembali.
Kedengarannya rumit? Waktu untuk contoh kode.
var p1 = api1(); // returning a promise
var p3 = p1.then(function(api1Result) {
var p2 = api2(); // returning a promise
return p2; // The result of p2 …
}); // … becomes the result of p3
// So it does not make a difference whether you write
api1().then(function(api1Result) {
return api2().then(console.log)
})
// or the flattened version
api1().then(function(api1Result) {
return api2();
}).then(console.log)
Meratakan tidak datang secara ajaib, tetapi Anda dapat dengan mudah melakukannya. Untuk contoh Anda yang sangat bersarang, yang setara (dekat) akan menjadi
api1().then(api2).then(api3).then(/* do-work-callback */);
Jika melihat kode dari metode ini membantu memahami, inilah janji paling mendasar dalam beberapa baris .
Apa masalah besar tentang janji?
Abstraksi Janji memungkinkan kompabilitas fungsi yang jauh lebih baik. Sebagai contoh, di sebelah then
untuk chaining, all
fungsi menciptakan janji untuk hasil gabungan dari janji-janji paralel ganda.
Last but not least Janji datang dengan penanganan kesalahan terintegrasi. Hasil perhitungannya bisa berupa apakah janji itu dipenuhi dengan nilai, atau ditolak dengan alasan. Semua fungsi komposisi menangani ini secara otomatis dan menyebarkan kesalahan dalam rantai janji, sehingga Anda tidak perlu mempedulikannya secara eksplisit di mana-mana - berbeda dengan implementasi panggilan balik biasa. Pada akhirnya, Anda dapat menambahkan callback kesalahan khusus untuk semua pengecualian yang terjadi.
Belum lagi harus mengubah hal-hal menjadi janji.
Itu cukup sepele sebenarnya dengan perpustakaan janji yang baik, lihat Bagaimana cara mengonversi API panggilan balik yang ada ke janji?