Janji dapat "ditangani" setelah ditolak. Artinya, seseorang dapat memanggil callback tolak janji sebelum memberikan catch handler. Perilaku ini sedikit mengganggu saya karena orang dapat menulis ...
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
... dan dalam hal ini, Janji itu ditolak secara diam-diam. Jika seseorang lupa menambahkan catch handler, kode akan terus berjalan tanpa kesalahan. Ini dapat menyebabkan bug yang bertahan dan sulit ditemukan.
Dalam kasus Node.js, ada pembicaraan tentang penanganan penolakan Janji yang tidak tertangani ini dan melaporkan masalahnya. Ini membawa saya ke ES7 async / menunggu. Pertimbangkan contoh ini:
async function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
let temp = await tempPromise;
// Assume `changeClothes` also returns a Promise
if(temp > 20) {
await changeClothes("warm");
} else {
await changeClothes("cold");
}
await teethPromise;
}
Dalam contoh di atas, misalkan toothPromise ditolak (Kesalahan: kehabisan pasta gigi!) Sebelum getRoomTemperature dipenuhi. Dalam hal ini, akan ada penolakan Janji yang tidak tertangani sampai menunggu gigi Janji.
Maksud saya adalah ini ... jika kita menganggap penolakan Janji yang tidak tertangani menjadi masalah, Janji yang nanti ditangani dengan menunggu mungkin akan dilaporkan secara tidak sengaja sebagai bug. Kemudian lagi, jika kami menganggap penolakan Janji yang tidak tertangani tidak menjadi masalah, bug yang sah mungkin tidak dilaporkan.
Pikiran tentang ini?
Ini terkait dengan diskusi yang ditemukan dalam proyek Node.js di sini:
Perilaku Deteksi Penolakan Tanpa Penanganan Default
jika Anda menulis kode dengan cara ini:
function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
return Promise.resolve(tempPromise)
.then(temp => {
// Assume `changeClothes` also returns a Promise
if (temp > 20) {
return Promise.resolve(changeClothes("warm"));
} else {
return Promise.resolve(changeClothes("cold"));
}
})
.then(teethPromise)
.then(Promise.resolve()); // since the async function returns nothing, ensure it's a resolved promise for `undefined`, unless it's previously rejected
}
Ketika getReadyForBed dipanggil, ia akan secara sinkron membuat janji terakhir (tidak dikembalikan) - yang akan memiliki kesalahan "penolakan tertangan" yang sama dengan janji lainnya (bisa jadi tidak ada apa-apa, tentu saja, tergantung pada mesinnya). (Saya merasa sangat aneh fungsi Anda tidak mengembalikan apa pun, yang berarti fungsi async Anda menghasilkan janji untuk tidak terdefinisi.
Jika saya membuat Janji sekarang tanpa tangkapan, dan menambahkannya nanti, sebagian besar implementasi "kesalahan penolakan tidak tertangani" sebenarnya akan menarik kembali peringatan ketika saya nanti menanganinya. Dengan kata lain, async / await tidak mengubah diskusi "penolakan yang tidak ditangani" dengan cara apa pun yang dapat saya lihat.
untuk menghindari jebakan ini, harap tulis kode seperti ini:
async function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
var clothesPromise = tempPromise.then(function(temp) {
// Assume `changeClothes` also returns a Promise
if(temp > 20) {
return changeClothes("warm");
} else {
return changeClothes("cold");
}
});
/* Note that clothesPromise resolves to the result of `changeClothes`
due to Promise "chaining" magic. */
// Combine promises and await them both
await Promise.all(teethPromise, clothesPromise);
}
Perhatikan bahwa ini harus mencegah penolakan janji yang tidak ditangani.