Async / await ile dosya nasıl düzgün okunur?


121

Nasıl async/ awaitçalıştığını anlayamıyorum. Biraz anlıyorum ama çalışmasını sağlayamıyorum.

function loadMonoCounter() {
    fs.readFileSync("monolitic.txt", "binary", async function(err, data) {
       return await new Buffer( data);
  });
}

module.exports.read = function() {
  console.log(loadMonoCounter());
};

Kullanabileceğimi biliyorum readFileSync, ama yaparsam asla anlayamayacağımı async/ awaitve meseleyi sadece gömeceğimi biliyorum .

Hedef: loadMonoCounter()Bir dosyanın içeriğini arayın ve iade edin.

Bu dosya her incrementMonoCounter()çağrıldığında artırılır (her sayfa yüklemesi). Dosya, ikili olarak bir arabellek dökümünü içerir ve bir SSD'de depolanır.

Ne yaparsam yapayım, undefinedkonsolda veya konsolda bir hata alıyorum .


Yanıtlar:


167

Sözleri geri döndüren yöntemleri kullanmak await/ asyncihtiyacınız var. Temel API işlevleri, aşağıdakiler gibi sarmalayıcılar olmadan bunu yapmaz promisify:

const fs = require('fs');
const util = require('util');

// Convert fs.readFile into Promise version of same    
const readFile = util.promisify(fs.readFile);

function getStuff() {
  return readFile('test');
}

// Can't use `await` outside of an async function so you need to chain
// with then()
getStuff().then(data => {
  console.log(data);
})

Not olarak, readFileSyncbir geri arama almaz, verileri döndürür veya bir istisna atar. İstediğiniz değeri alamıyorsunuz çünkü sağladığınız bu işlev göz ardı ediliyor ve gerçek dönüş değerini yakalayamıyorsunuz.


3
Teşekkürler, temel API'yi paketlemem gerektiğini bilmiyordum. Müthişsin.
Jeremy Dicaire

4
Temel API, modern Promise spesifikasyonunun ve async/ kullanımının önceden tarihlendirilmesidir await, bu nedenle bu gerekli bir adımdır. İyi haber, promisifygenellikle dağınıklık olmadan çalışmasını sağlar.
tadman

1
Bu, FS ile zaman uyumsuz bekleme durumundan normal olarak yararlanamamanın karmaşasını çözer. Bunun için teşekkür ederim! Beni bir ton kurtardın! Seninki gibi buna hitap eden bir cevap yok.
jacobhobson

3
Ayrıca await, çıkarsama yapılabileceği için biraz gereksizdir. Sadece açıkça örnek olarak beklemek istiyorsanız, yapabilirsiniz const file = await readFile...; return file;.
bigkahunaburger

1
@shijin Node çekirdek API'si vaatlere geçene kadar ki bu şu anda pek olası değil, o zaman evet. Yine de bunu sizin için yapan NPM sarmalayıcılar var.
tadman

152

Node v11.0.0'dan beri fs vaatleri aşağıdakiler olmadan yerel olarak kullanılabilir promisify:

const fs = require('fs').promises;
async function loadMonoCounter() {
    const data = await fs.readFile("monolitic.txt", "binary");
    return new Buffer(data);
}

4
ek
kitap

2
21-Ekim-2019 itibariyle, v12 aktif bir LTS sürümüdür
cbronson

16
import { promises as fs } from "fs";içe aktarma sözdizimini kullanmak istiyorsanız.
tr3online

21

Bu, @ Joel'in cevabının TypeScript sürümüdür. Düğüm 11.0'dan sonra kullanılabilir:

import { promises as fs } from 'fs';

async function loadMonoCounter() {
    const data = await fs.readFile('monolitic.txt', 'binary');
    return Buffer.from(data);
}

18

ReadFile komutunu aşağıdaki gibi bir sözle kolayca sarabilirsiniz:

async function readFile(path) {
    return new Promise((resolve, reject) => {
      fs.readFile(path, 'utf8', function (err, data) {
        if (err) {
          reject(err);
        }
        resolve(data);
      });
    });
  }

sonra kullan:

await readFile("path/to/file");

Async işlevi içinde kullanılmayı beklemiyor musunuz?
VikasBhat

@VikasBhat Evet, yukarıdaki bekleme satırı, spesifikasyon gerektirdiği için başka bir zaman uyumsuz işlev içinde kullanılacaktır.
whoshotdk

8

Sen kullanabilirsiniz fs.promisesDüğüm v11.0.0 beri mevcut doğal

import fs from 'fs';

const readFile = async filePath => {
  try {
    const data = await fs.promises.readFile(filePath, 'utf8')
    return data
  }
  catch(err) {
    console.log(err)
  }
}

Yalnızca sözleri kullanmak istiyorsan şöyle bir şey yapabilirsinconst fs = require('fs').promises
nathanfranke

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.