fs/promises, Node'un fs modülünün promise tabanlı sürümüdür. Fonksiyonları (readFile, writeFile, readdir, stat, mkdir, rm, rename ve diğerleri) callback almak yerine bir promise döndürür, böylece onları await eder ve hataları try/catch ile yakalarsın. require('fs/promises') ya da import fs from 'fs/promises' ile import et.
Çıktı [ 'write docs', 'ship it' ] olur: her await sonraki satır çalışmadan önce bir işlemi bekler, bu yüzden ekleme her zaman ilk yazmadan sonra olur. Bir ES modülünde await en üst seviyede çalışır; CommonJS'te kodu bir async fonksiyonun içine sar.
En çok kullanacağın fonksiyonlar
İsimler callback API'siyle aynı, sadece callback yok. O ikisini readFile ve writeFile sayfaları ayrıntılı anlatıyor.
| Fonksiyon | Ne yapar | Neye resolve olur |
|---|---|---|
readFile(path, 'utf8') | Bütün bir dosyayı okur | İçerik |
writeFile(path, data) | Bir dosya oluşturur ya da üzerine yazar | undefined |
appendFile(path, data) | Sona ekler | undefined |
readdir(path) | Bir klasörü listeler | İsimlerden oluşan bir dizi |
stat(path) | Boyut, tarihler, dosya mı klasör mü | Bir Stats nesnesi |
mkdir(path, { recursive: true }) | Klasör oluşturur | Oluşturulan ilk klasör ya da undefined |
rename(from, to) | Taşır ya da yeniden adlandırır | undefined |
rm(path, { recursive: true, force: true }) | Bir dosyayı ya da klasörü siler | undefined |
readdir ve stat ile bir klasörü listele
readdir yalnızca isimleri döndürür. Boyutunu almak ya da dosyaları klasörlerden ayırmak için her birinde stat çağır, ya da tipini zaten bilen girdiler almak için { withFileTypes: true } ver.
Döngü README.md 6 bytes, notes.txt 3 bytes ve src folder yazdırır. stat, var olmayan bir path için ENOENT ile reject olur, bu da ayrıntıları da istediğinde onu hızlı bir varlık kontrolü yapar.
Yeniden adlandır, taşı ve sil
rename bir dosyayı hem yeniden adlandırır hem de taşır (aynı sürücü içinde). rm siler; içi dolu bir klasör için recursive: true, path zaten yoksa hata vermemesi için de force: true gerekir.
Dosya yeni ismiyle drafts klasöründen published klasörüne taşınır ve rm sonrasında blog klasörü yalnızca published listeler. İkinci rm çağrısından force: true seçeneğini kaldırırsan ENOENT ile reject olur.
Hataları try/catch ile yakala
Başarısız bir işlem kendi promise'ini reject eder. await ile bu reject, diğerleri gibi yakaladığın bir exception'a dönüşür. Hatanın code değeri neyin ters gittiğini söyler.
İlk çağrı dosya bulamaz ve [] döndürür; ikincisi Ada yazdırır. Bilmen gereken kodlar: ENOENT (böyle bir dosya yok), EEXIST (zaten var), EISDIR (dosya beklenen yerde klasör var), ENOTEMPTY (klasörün içinde hâlâ bir şeyler var) ve EACCES (izin yok).
await etmediğin ve .catch() eklemediğin bir promise başarısız olduğunda unhandled rejection'a dönüşür ve Node hata ile çıkar. Her çağrıyı await et ya da promise'ini await eden bir çağırana döndür.
Promise.all ile birkaç dosyayı aynı anda oku
await içeren bir for döngüsü dosyaları birbiri ardına okur. Okumalar birbirine bağlı değilse hepsini başlat ve Promise.all ile bir kez bekle: disk onlar üzerinde aynı anda çalışır.
Promise.all giriş dizisinin sırasını korur, bu yüzden hangi okuma önce biterse bitsin sonuç [ 'alpha', 'beta', 'gamma' ] olur ve birleştirilmiş uzunluk 14 olur. Dizideki 'b.txt' değerini 'x.txt' yap, bütün await ENOENT ile reject olur.
Bazı okumalar başarısız olsa bile her sonuca ihtiyacın varsa Promise.allSettled kullan; ikisini de promise'ler sayfası anlatıyor.
Sık yapılan hatalar
İki modülü karıştırmak. require('fs').readFile bir callback ister; require('fs/promises').readFile ise bir promise döndürür. Callback sürümünü callback olmadan çağırmak The "cb" argument must be of type function fırlatır.
await unutmak. const text = fs.readFile(...) bekleyen bir promise'tir ve text.split, text.split is not a function fırlatır.
Tek bir dosyaya paralel yazmak. Aynı path'e birkaç yazma içeren bir Promise.all karışık içerik bırakabilir. Bunları sırayla çalıştır.
Sıkça Sorulan Sorular
fs.promises ile fs/promises arasındaki fark nedir?
Hiçbir fark yok. require('fs').promises ve require('fs/promises') aynı nesnedir. Bugün onu import etmenin olağan yolu fs/promises path'idir (ya da node:fs/promises).
fs/promises içinde existsSync var mı?
Hayır. Promise API'sinde path yoksa reject olan access vardır, ama olağan kalıp ihtiyacın olan işlemi çağırıp ENOENT hatasını yakalamaktır. Hızlı kontroller için düz fs modülündeki existsSync hâlâ çalışır.
fs/promises callback API'sinden daha mı yavaş?
Promise yükü yüzünden biraz, ama disk süresinin yanında önemsiz. Okunabilirliğe göre seç; yeni kodun çoğu promise API'sini kullanıyor.
Callback'li bir fs fonksiyonunu promise'e nasıl çeviririm?
Buna nadiren ihtiyacın olur, çünkü fs/promises dosya fonksiyonlarını kapsar. Diğer callback API'leri için util.promisify(fn) promise döndüren bir sürüm verir.