node.js 如何正确使用异步/等待读取文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46867517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:32:48  来源:igfitidea点击:

How to read file with async/await properly?

node.jsasynchronousreadfile

提问by Jeremy Dicaire

I cannot figure out how async/awaitworks. I slightly understands it but I can't make it work.

我无法弄清楚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());
};

I know I could use readFileSync, but if I do, I know I'll never understand async/awaitand I'll just bury the issue.

我知道我可以使用readFileSync,但如果我这样做了,我知道我永远不会理解async/await并且我只会埋葬这个问题。

Goal: Call loadMonoCounter()and return the content of a file.

目标:调用loadMonoCounter()并返回文件的内容。

That file is incremented every time incrementMonoCounter()is called (every page load). The file contain the dump of a buffer in binary and is stored on a SSD.

每次incrementMonoCounter()调用(每次加载页面)时,该文件都会增加。该文件包含二进制缓冲区的转储,并存储在 SSD 上。

No matter what I do, I get an error or undefinedin the console.

无论我做什么,都会出现错误或undefined在控制台中。

回答by tadman

To use await/asyncyou need methods that return promises. The core API functions don't do that without wrappers like promisify:

要使用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);
})

As a note, readFileSyncdoes not take a callback, it returns the data or throws an exception. You're not getting the value you want because that function you supply is ignored and you're not capturing the actual return value.

注意,readFileSync不接受回调,它返回数据或抛出异常。你没有得到你想要的值,因为你提供的函数被忽略了,你没有捕获实际的返回值。

回答by Joel

Since Node v11.0.0 fs promises are available natively without promisify:

由于 Node v11.0.0 fs 承诺在本机可用,而无需promisify

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

回答by Shlomi Schwartz

You can easily wrap the readFile command with a promise like so:

您可以使用如下承诺轻松包装 readFile 命令:

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

then use:

然后使用:

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

回答by HKTonyLee

This is TypeScript version of @Joel's answer. It is usable after Node 11.0:

这是@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);
}

回答by arnaudjnn

You can use fs.promisesavailable natively since Node v11.0.0

fs.promises从 Node 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)
  }
}