Bir Söz ile neden tarayıcılar iki kez reddetme döndürüyor ancak iki kez çözüm vermiyor?


10

JavaScript'i anlamada sorun yaşıyorum promises. Aşağıdaki kodu yazdım:

var p = new Promise(function(resolve,reject){

    reject(Error("hello world"));
});

setTimeout(()=>p.catch(e=>console.log(e)),5000);

Bunu Chrome geliştirici konsolumda hemen görüyorum: resim açıklamasını buraya girin

Ama 5 saniye bekledikten sonra, mesaj bu görüntü gibi otomatik olarak siyaha döner: resim açıklamasını buraya girin

JavaScript kodum ile javaScript kodumun geliştirici konsolunda "mevcut içeriği değiştirebileceği" geliştirici konsolu arasında daha önce hiç bu davranışı görmedim.

Bu nedenle, resolvebu kodu yazarak aynı durumun meydana gelip gelmediğini görmeye karar verdim :

var p = new Promise(function(resolve,reject){

    resolve("hello world");
});

setTimeout(()=>p.then(e=>console.log(e)),5000);

Ancak bu durumda, geliştirici konsolum 5 saniye sonrasına kadar hiçbir şey göstermiyor ve daha sonra yazdırılıyor hello world.

Neden çağrıldıkları zaman resolveve neden rejectbu kadar farklı davranılıyor?


EKSTRA

Ayrıca bu kodu yazdım:

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);

Bu, geliştirici konsolunda birkaç çıkışa neden olur. 0 zamanında kırmızı hata, kırmızı metin 5 saniyede siyah errors hello world, sonra 6 saniyede yeni bir hata mesajı, 7 saniyede errors 2 hello worldkırmızı bir hata mesajı. Şimdi rejectgerçekten kaç kez çağrıldığına çok şaşkınım .... Kayboldum ...


1
Bir kenara: var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });daha deyimsel ve kısaca var p = Promise.reject(Error("hello world"));:-) olarak yazılabilir
TJ Crowder

1
Harika bir soru.
TJ Crowder

Yanıtlar:


11

Vay canına, bu gerçekten harika. Konsolun daha önce bunu yaptığını hiç görmemiştim. (Bununla birlikte, başka dinamik davranış biçimleri de vardır , bu yüzden ...) İşte olanlar:

İlk durumda, setTimeoutgeri arama kodunuzun dışındaki her şeyin kod yürütmesi tamamlanır ve yürütme yığını , kullanıcı tarafından kullanılan JavaScript kodu (şu an için değil) yalnızca " platform kodu " (Promises / A + spec'in çağırdığı gibi) çalıştığı şekilde döner . Bu noktada, söz reddedilir ve reddi hiçbir şey halletmez , bu yüzden işlenmeyen bir rettir ve devtools bunu size bildirir.

Ardından , beş saniye sonra geri aramanız çalışır ve bir ret işleyicisi ekler. Bu noktada, ret artık ele alınmamaktadır. Görünüşe göre, Chrome / V8 / devtools , işlenmeyen ret uyarısını konsoldan kaldırmak için birlikte çalışıyor . Bunun yerine, gördüğünüz şey, reddedici işleyiciniz aracılığıyla çıkardığınız şeydir console.log. Reddetme işleyicisini daha erken eklediyseniz, işlenmeyen ret hatasını almazsınız.

Bu yerine getirme ile olmaz çünkü yerine getirme işleminin gerçekleştirilmemesi bir hata koşulu değildir. Reddetme ile başa çıkmak değildir.


1
Ah, bu mantıklı. FireFox'un biraz farklı işlediğini fark ettim. Ama tamam, şimdi daha mantıklı.
John

1
Ben de aynı cevabı yazdım, ama SO seninkini yükledi, bu yüzden benimkini göndermedim. Güzel açıklama! +1
FZ'ler
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.