Seperti yang saya pahami, sebuah promise adalah sesuatu yang dapat menyelesaikan () atau menolak () tetapi saya terkejut saat mengetahui bahwa kode dalam promise terus dijalankan setelah penyelesaian atau penolakan dipanggil.
Saya mempertimbangkan untuk menyelesaikan atau menolak menjadi versi keluar atau kembali yang ramah asinkron, yang akan menghentikan semua eksekusi fungsi langsung.
Adakah yang bisa menjelaskan pemikiran di balik mengapa contoh berikut terkadang menunjukkan console.log setelah panggilan penyelesaian:
var call = function() {
return new Promise(function(resolve, reject) {
resolve();
console.log("Doing more stuff, should not be visible after a resolve!");
});
};
call().then(function() {
console.log("resolved");
});
javascript
promise
ecmascript-6
es6-promise
Ludwig Van Beethoven
sumber
sumber
resolve()
bukanlah pernyataan kontrol JS yang secara ajaib akan memiliki efekreturn
, itu hanya pemanggilan fungsi, dan ya, eksekusi berlanjut setelahnya.Jawaban:
JavaScript memiliki konsep "run to finish" . Kecuali jika terjadi kesalahan, suatu fungsi dijalankan hingga
return
pernyataan atau akhirnya tercapai. Kode lain di luar fungsi tidak dapat mengganggu itu (kecuali, sekali lagi, terjadi kesalahan).Jika Anda ingin
resolve()
keluar dari fungsi penginisialisasi, Anda harus menambahkannya denganreturn
:sumber
resolve()
fungsi asinkron itu sendiri. Seperti yang kita lihat di jawaban (dihapus) lainnya, beberapa orang percaya bahwa panggilanresolve
akan segera menjalankan panggilan balik apa pun.resolve
itu sendiri tidak asinkron, itu sepenuhnya sinkron. Meskipun menggunakan ES6 API secara ketat, itu tidak dapat diamati apakah itu sinkron atau asinkron.resolve
akan mengakibatkan panggilan balik terdaftar segera dipanggil sedemikian rupa sehingga mereka adalah bagian dari tumpukan panggilan saat ini. Itu tidak benar, melainkan hanya mengantri panggilan balik (dan Anda benar, ini tidak asinkron, tetapi itu hanya melakukan hal itu dan segera berakhir)console.log
pertunjukan itu muncul di alih-alih mengapa itu muncul dalam urutan itu. Sejauh ini, aparesolve
dan bagaimana janji tidak relevan dengan bagaimana saya menafsirkan pertanyaan itu. Namun tentunya tetap penting untuk mengetahui konteks dari promise. Salah satu alasan saya menaikkan suara jawaban Anda :)Callback yang akan dipanggil saat Anda
resolve
membuat janji masih diperlukan oleh spesifikasi agar bisa dipanggil secara asinkron. Ini untuk memastikan perilaku yang konsisten saat menggunakan promise untuk campuran tindakan sinkron dan asinkron.Oleh karena itu, saat Anda memanggil
resolve
callback dalam antrean , dan eksekusi fungsi segera dilanjutkan dengan kode apa pun setelahresolve()
panggilan tersebut.Hanya setelah loop peristiwa JS diberikan kontrol kembali, callback dapat dihapus dari antrian dan benar-benar dipanggil.
sumber
EnqueueJob
, yang dipanggil oleh.then
.