Saya mengalami kesulitan memahami javaScript promises
. Saya menulis kode berikut:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Saya segera melihat ini di konsol pengembang Chrome saya:
Tetapi setelah saya menunggu 5 detik, pesan secara otomatis berubah menjadi hitam seperti gambar ini:
Saya belum pernah melihat perilaku ini sebelumnya antara kode javaScript saya dan konsol pengembang, di mana kode javaScript saya dapat "memodifikasi konten yang ada" di konsol pengembang.
Jadi saya memutuskan untuk melihat apakah situasi yang sama terjadi dengan resolve
menulis kode ini:
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
Tetapi dalam situasi ini, konsol pengembang saya tidak menunjukkan apa-apa sampai 5 detik kemudian, yang kemudian dicetak hello world
.
Mengapa resolve
dan reject
diperlakukan begitu berbeda dalam hal ketika mereka dipanggil?
TAMBAHAN
Saya juga menulis kode ini:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);
Ini menyebabkan beberapa keluaran ke konsol pengembang. Kesalahan merah pada waktu 0, merah berubah menjadi hitam pada waktu 5 detik dengan teks errors hello world
, kemudian pesan kesalahan baru pada waktu 6 detik errors 2 hello world
, kemudian pesan kesalahan merah pada waktu 7 detik. Sekarang saya sangat bingung berapa kali reject
benar-benar dipanggil .... Saya tersesat ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
bisa ditulis secara lebih idiomatis dan ringkas sebagaivar p = Promise.reject(Error("hello world"));
:-)Jawaban:
Wow, itu sangat keren. Saya belum pernah melihat konsol melakukan itu sebelumnya. (Ini memiliki bentuk lain dari perilaku dinamis, jadi ...) Inilah yang terjadi:
Dalam kasus pertama, eksekusi kode dari segala sesuatu di luar
setTimeout
kode callback Anda selesai dan tumpukan eksekusi kembali sehingga hanya " kode platform " (seperti yang dijanjikan oleh spec / A +), yang sedang berjalan, bukan kode JavaScript pengguna lahan (untuk saat ini). Pada saat itu, janji itu ditolak dan tidak ada yang ditangani penolakan, jadi itu adalah penolakan tertangani dan devtools melaporkan kepada Anda seperti itu.Kemudian , lima detik kemudian, panggilan balik Anda berjalan dan menempel handler penolakan. Pada titik ini, penolakan tidak lagi ditangani. Tampaknya, Chrome / V8 / devtools bekerja bersama untuk menghapus peringatan penolakan yang tidak ditangani dari konsol. Apa yang Anda lihat muncul sebagai gantinya adalah apa yang Anda hasilkan di handler penolakan melalui
console.log
. Jika Anda memasang reler handler lebih awal, Anda tidak akan mendapatkan kesalahan penolakan yang tidak ditangani.Ini tidak terjadi dengan pemenuhan karena tidak menangani pemenuhan bukanlah kondisi kesalahan. Tidak menangani penolakan.
sumber