Kesin olanları anlamak için senaryonuzda bazı değişiklikler yapmam gerekiyordu, ama işte burada.
İlk olarak, nasıl node
ve nasıl event loop
çalıştığını biliyor olabilirsiniz , ancak hızlı bir özet yapmama izin verin. Bir komut dosyasını çalıştırdığınızda, node
çalışma zamanı önce eşzamanlı kısmını çalıştırır ve sonraki döngülerde çalıştırılacak promises
ve zamanlanacak şekilde zamanlanır ve timers
çözümlendiğinde, geri çağrıları başka bir döngüde çalıştırın. Bu basit özü, @StephenGrider'a çok iyi açıklıyor:
const pendingTimers = [];
const pendingOSTasks = [];
const pendingOperations = [];
// New timers, tasks, operations are recorded from myFile running
myFile.runContents();
function shouldContinue() {
// Check one: Any pending setTimeout, setInterval, setImmediate?
// Check two: Any pending OS tasks? (Like server listening to port)
// Check three: Any pending long running operations? (Like fs module)
return (
pendingTimers.length || pendingOSTasks.length || pendingOperations.length
);
}
// Entire body executes in one 'tick'
while (shouldContinue()) {
// 1) Node looks at pendingTimers and sees if any functions
// are ready to be called. setTimeout, setInterval
// 2) Node looks at pendingOSTasks and pendingOperations
// and calls relevant callbacks
// 3) Pause execution. Continue when...
// - a new pendingOSTask is done
// - a new pendingOperation is done
// - a timer is about to complete
// 4) Look at pendingTimers. Call any setImmediate
// 5) Handle any 'close' events
}
// exit back to terminal
Olay döngüsünün, bekleyen OS görevleri olana kadar hiçbir zaman sona ermeyeceğini unutmayın. Başka bir deyişle, bekleyen HTTP istekleri olana kadar düğüm yürütmeniz hiçbir zaman sona ermeyecektir.
Sizin durumunuzda, async
her zaman bir söz döndüreceği için bir işlevi çalıştırır, bir sonraki döngü yinelemesinde yürütülmesini zamanlar. Eşzamansız işlevinizde, bu yinelemede bir defada başka 1000 vaat (HTTP isteği) zamanlayabilirsiniz map
. Bundan sonra, programı bitirmek için hepsini çözmeyi bekliyorsunuz. Anonim ok işleviniz map
herhangi bir hata atmazsa, kesinlikle çalışacaktır . Sözünde biri bir hata atar ve bunu işlemek yoksa, sözlerin bazılarının geri arama programı yapma hiç denilen olmayacak sona ama değil çıkışında olay döngü o giderir kadar çıkmak için bunu engelleyecektir, çünkü tüm görevler, geri arama olmadan bile. Üzerinde dediği gibiPromise.all
dokümanlar : ilk söz reddedilir reddedilmez.
Yani, ECONNRESET
hata durumunda düğümün kendisi ile ilgili değildir, ağınızda bir hata atmak için getirilen ve daha sonra olay döngüsünün bitmesini önleyen bir şeydir. Bu küçük düzeltmeyle, tüm isteklerin eşzamansız olarak çözüldüğünü görebilirsiniz:
const fetch = require("node-fetch");
(async () => {
try {
const promises = Array(1000)
.fill(1)
.map(async (_value, index) => {
try {
const url = "https://google.com/";
const response = await fetch(url);
console.log(index, response.statusText);
return response;
} catch (e) {
console.error(index, e.message);
}
});
await Promise.all(promises);
} catch (e) {
console.error(e);
} finally {
console.log("Done");
}
})();
npx envinfo
, 8432.805ms benim Win 10 / nodev10.16.0 komut ucunda seni örnek çalıştıran