Bu, altına inmek için harika bir soru.
Bunu yaptığınızda:
verifier(3,4).then(...)
bu, yeni reddedilen sözün .catch()takip eden işleyiciyi çalıştırabilmesi için olay döngüsüne başka bir döngü gerektiren yeni bir söz döndürür . Bu ekstra döngü bir sonraki sırayı verir:
verifier(5,4).then(...)
.then()işleyicisini önceki satırdan önce çalıştırma şansı, .catch()çünkü ilk satırdaki .catch()işleyici kuyruğa girmeden ve öğeler kuyruktan FIFO sırasına göre çalıştırılmadan önce zaten kuyruktaydı .
.then(f1, f2)Formu yerine kullanırsanız, .then().catch()beklediğinizde çalışacağını unutmayın, çünkü ek bir söz yoktur ve bu nedenle ek bir onay söz konusu değildir:
const verifier = (a, b) =>
new Promise((resolve, reject) => (a > b ? resolve(true) : reject(false)));
verifier(3, 4)
.then((response) => console.log("response (3,4): ", response),
(error) => console.log("error (3,4): ", error)
);
verifier(5, 4)
.then((response) => console.log("response (5,4): ", response))
.catch((error) => console.log("error (5,4): ", error));
Ayrıca, tüm mesajları etiketledim, böylece hangi verifier()aramadan geldiklerini görebilirsiniz , bu da çıktıyı okumayı çok daha kolay hale getirir.
ES6 Söz geri arama sıralaması ve daha ayrıntılı açıklama hakkında spesifikasyon
(Bir bir geri deyişiyle ES6 Spec bize bu söz "işler" söyler .then()veya .catch()onlar iş kuyruğuna takıldığında dayalı FIFO sırayla çalıştırılır). Özel olarak FIFO adını vermez, ancak kuyruğun sonuna yeni işlerin eklendiğini ve işlerin kuyruğun başından itibaren çalıştırıldığını belirtir. Bu, FIFO siparişini uygular.
PerformPromiseThen (geri aramayı yürütür .then()) EnqueueJob'a yol açar, bu da çözümleme veya reddetme işleyicisinin gerçekte çalıştırılmak üzere planlandığı şekilde gerçekleşir. EnqueueJob, bekleyen işin iş kuyruğunun arkasına eklendiğini belirtir. Ardından NextJob işlemi, öğeyi kuyruğun önünden çeker. Bu, Promise iş kuyruğundan işlerin hizmetinde FIFO siparişini sağlar.
Dolayısıyla, orijinal sorudaki örnekte, verifier(3,4)sözün geri aramalarını ve verifier(5,4)çalıştırıldıkları sırayla iş kuyruğuna eklenen sözün her ikisi de orijinal sözler yerine getirildiğinden alıyoruz . Ardından, yorumlayıcı olay döngüsüne geri döndüğünde, önce verifier(3,4)işi alır. Bu söz reddedildi ve bunun için verifier(3,4).then(...). Yani, yaptığı şey verifier(3,4).then(...)geri dönen sözü reddetmektir ve bu da verifier(3,4).then(...).catch(...)işleyicinin jobQueue'ya eklenmesine neden olur .
Daha sonra olay döngüsüne geri döner ve jobQueue'dan aldığı bir sonraki iş verifier(5, 4)iştir. Çözülmüş bir sözü ve bir çözümleyici işleyiciye sahip olduğundan, bu işleyiciyi çağırır. Bu, response (5,4):çıktının gösterilmesine neden olur .
Daha sonra olay döngüsüne geri döner ve jobQueue'dan çektiği bir sonraki iş, verifier(3,4).then(...).catch(...)bunu çalıştırdığı iştir ve bu da error (3,4)çıktının gösterilmesine neden olur .
Bunun nedeni, .catch()1. zincirin, .then()bildirdiğiniz siparişe neden olan, 2. zincirdekinden daha derin bir vaat seviyesi olmasıdır. Bunun nedeni, vaat zincirlerinin eşzamanlı olarak değil, FIFO sırasındaki iş kuyruğu aracılığıyla bir seviyeden diğerine geçmesidir.
Bu Seviye Çizelgeleme Ayrıntılarına Güvenmek Hakkında Genel Öneri
Bilginize, genel olarak, bu detaylı zamanlama bilgisine bağlı olmayan bir kod yazmaya çalışıyorum. Tuhaf ve bazen anlaşılması yararlı olsa da, kodda basit görünen zararsız bir değişiklik göreceli zamanlamada bir değişikliğe yol açabileceğinden kırılgan bir koddur. Öyleyse, zamanlama bunun gibi iki zincir arasında kritikse, kodu, bu ayrıntılı anlayış düzeyine güvenmektense, zamanlamayı istediğim şekilde zorlayacak şekilde yazmayı tercih ederim.