Bunun nasıl yanlış gidebileceğini görmek için yöntemin sonunda console.log yazdırın.
Genel olarak yanlış gidebilecek şeyler:
- Keyfi düzen.
- printFiles dosyaları yazdırmadan önce çalışmayı bitirebilir.
- Zayıf performans.
Bunlar her zaman yanlış değildir ancak sıklıkla standart kullanım durumlarındadır.
Genellikle, forEach kullanımı sonuncusu dışında her şeyle sonuçlanır. Fonksiyonu beklemeden her fonksiyonu çağırır, yani tüm fonksiyonların başlamasını söyler ve fonksiyonların bitmesini beklemeden biter.
import fs from 'fs-promise'
async function printFiles () {
const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'))
for(const file of files)
console.log(await file)
}
printFiles()
Bu, yerel JS'de düzeni koruyan, işlevin erken dönmesini önleyen ve teoride en iyi performansı koruyan bir örnektir.
Bu irade:
- Tüm dosya okumalarını paralel olarak başlatın.
- Bekleneceği vaat edilen dosya adlarını eşlemek için haritayı kullanarak siparişi koruyun.
- Her vaat için dizi tarafından tanımlanan sırada bekleyin.
Bu çözümle, ilk dosya, diğerlerinin ilk önce kullanılabilir olmasını beklemek zorunda kalmadan en kısa sürede gösterilecektir.
Ayrıca, ikinci dosya okunmaya başlamadan önce ilkinin bitmesini beklemek yerine tüm dosyaları aynı anda yükleyecektir.
Bunun ve orijinal versiyonun tek dezavantajı, aynı anda birden fazla okuma başlatılırsa, aynı anda olabilecek daha fazla hata olması nedeniyle hataları işlemenin daha zor olmasıdır.
Bir kerede bir dosyayı okuyan sürümlerle, daha fazla dosyayı okumaya çalışırken zaman kaybetmeden bir arızada durur. Ayrıntılı bir iptal sistemiyle bile, ilk dosyada başarısız olmasını önlemek, ancak diğer dosyaların çoğunu zaten okumaktan kaçınmak zor olabilir.
Performans her zaman öngörülebilir değildir. Birçok sistem paralel dosya okumaları ile daha hızlı olurken, bazıları sıralı tercih eder. Bazıları dinamiktir ve yük altında kayabilir, gecikme sunan optimizasyonlar ağır çekişme altında her zaman iyi verim vermez.
Bu örnekte hata işleme de yoktur. Bir şey bunların hepsinin başarıyla gösterilmesini veya hiç gösterilmemesini gerektiriyorsa, bunu yapmayacaktır.
Her aşamada console.log ve sahte dosya okuma çözümleri (bunun yerine rastgele gecikme) ile derinlemesine deneme yapılması önerilir. Her ne kadar birçok çözüm basit durumlarda aynı şeyi yapıyor gibi görünse de, hepsinin sıkmak için ekstra inceleme gerektiren ince farklılıkları vardır.
Çözümler arasındaki farkı anlatmaya yardımcı olması için bu taklidi kullanın:
(async () => {
const start = +new Date();
const mock = () => {
return {
fs: {readFile: file => new Promise((resolve, reject) => {
// Instead of this just make three files and try each timing arrangement.
// IE, all same, [100, 200, 300], [300, 200, 100], [100, 300, 200], etc.
const time = Math.round(100 + Math.random() * 4900);
console.log(`Read of ${file} started at ${new Date() - start} and will take ${time}ms.`)
setTimeout(() => {
// Bonus material here if random reject instead.
console.log(`Read of ${file} finished, resolving promise at ${new Date() - start}.`);
resolve(file);
}, time);
})},
console: {log: file => console.log(`Console Log of ${file} finished at ${new Date() - start}.`)},
getFilePaths: () => ['A', 'B', 'C', 'D', 'E']
};
};
const printFiles = (({fs, console, getFilePaths}) => {
return async function() {
const files = (await getFilePaths()).map(file => fs.readFile(file, 'utf8'));
for(const file of files)
console.log(await file);
};
})(mock());
console.log(`Running at ${new Date() - start}`);
await printFiles();
console.log(`Finished running at ${new Date() - start}`);
})();
for ... of ...
işe yaradığını açıklayabilir misiniz ?