async / await로 파일을 올바르게 읽는 방법은 무엇입니까?


120

나는 어떻게 async/ await작동 하는지 알 수 없다 . 나는 그것을 약간 이해하지만 작동시킬 수 없습니다.

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

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

내가 사용할 수 있습니다 알고 readFileSync있지만 내가 할 경우, 나는 결코 이해하지 못할 것 알고 async/ await난 그냥 문제를 묻어 있습니다.

목표 : loadMonoCounter()파일의 내용을 호출 하고 반환합니다.

해당 파일은 incrementMonoCounter()호출 될 때마다 증가합니다 (모든 페이지로드). 이 파일은 바이너리 버퍼 덤프를 포함하며 SSD에 저장됩니다.

내가 무엇을하든 undefined콘솔에 오류가 발생 합니다.


답변:


165

사용하려면 await/ async약속을 반환하는 메서드가 필요합니다. 핵심 API 함수는 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);
})

참고 readFileSync로 콜백을받지 않고 데이터를 반환하거나 예외를 throw합니다. 제공하는 함수가 무시되고 실제 반환 값을 캡처하지 않기 때문에 원하는 값을 얻지 못합니다.


3
감사합니다. 핵심 API를 래핑해야한다는 사실을 몰랐습니다. 당신은 대단합니다.
Jeremy Dicaire

4
핵심 API는 최신 Promise 사양과 async/ 채택보다 앞서 await있으므로 필수 단계입니다. 좋은 소식은 promisify일반적으로 엉망이없이 작동한다는 것입니다.
tadman

1
이것은 FS로 async-await를 정상적으로 활용할 수 없다는 혼란을 처리합니다. 감사합니다! 당신은 나에게 많은 것을 구했습니다! 이 문제를 실제로 해결하는 답변은 없습니다.
jacobhobson

3
또한 await는 추론 할 수 있기 때문에 다소 중복됩니다. 예를 들어 명시 적으로 await를 사용하려는 경우에만 const file = await readFile...; return file;.
bigkahunaburger 19.01.26

1
@shijin Node 코어 API가 약속으로 전환 될 때까지,이 시점에서는 가능성이 낮습니다. 하지만 당신을 위해 그것을하는 NPM 래퍼가 있습니다.
tadman dec

150

Node v11.0.0 fs promise는 기본적으로 다음없이 사용할 수 있습니다 promisify.

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

4
아니, 깨끗하고 간단한 추가 libs와 -이해야 바람직 대답
아담 Bubela

2
2019 년 10 월 21 일 현재 v12는 활성 LTS 버전입니다
cbronson

16
import { promises as fs } from "fs";가져 오기 구문을 사용하려는 경우.
tr3online

21

이것은 @Joel의 대답의 TypeScript 버전입니다. Node 11.0 이후에 사용할 수 있습니다.

import { promises as fs } from 'fs';

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

18

readFile 명령을 다음과 같은 약속으로 쉽게 래핑 할 수 있습니다.

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

그런 다음 다음을 사용하십시오.

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

await는 비동기 함수 내에서 사용되지 않습니까?
VikasBhat

@VikasBhat 예, 위의 await 줄은 사양에 따라 필요하므로 다른 비동기 함수 내에서 사용됩니다.
whoshotdk

8

fs.promisesNode v11.0.0부터 기본적으로 사용할 수 있습니다.

import fs from 'fs';

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

promise 만 사용하려면 다음과 같이 할 수 있습니다.const fs = require('fs').promises
nathanfranke

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.