如何正确读取async/await文件?

Jer*_*ire 71 asynchronous readfile node.js

我无法弄清楚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());
};
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用readFileSync,但是如果我这样做,我知道我永远不会理解async/await,我只会把问题埋没.

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

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

不管我做什么,我在控制台中得到错误或未定义.

tad*_*man 133

要使用await/ async你需要返回promises的方法.没有包装器,核心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);
})
Run Code Online (Sandbox Code Playgroud)

作为注释,readFileSync不进行回调,它返回数据或抛出异常.您没有获得所需的值,因为您提供的功能被忽略,而您没有捕获实际的返回值.

  • 核心API早于现代Promise规范和采用`async` /`await`,因此这是必要的步骤.好消息是`promisify`通常会使它无故障地工作. (4认同)
  • 等待有点多余,因为它可以被推测.只有当你想在示例中明确地拥有await时,你才能做`const file = await readFile ...; 返回文件;`. (3认同)
  • 谢谢,我不知道我需要包装核心API.你太棒了. (2认同)

Joe*_*oel 48

由于Node v11.0.0 fs promises可以在没有以下情况的情况下本地使用promisify

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

  • 如果你想使用导入语法,请使用 import { Promise as fs } from "fs"; 。 (52认同)
  • 没有额外的库,干净简单 - 这应该是更好的答案 (9认同)
  • 提示:调用 `await fs.readFile("monolitic.txt", "utf8");` 以字符串形式获取文件内容 (6认同)
  • 关于此方法的注释,虽然它很干净,但它也不会在 `fs.promises` api 之外导入 `fs` 的其他有用功能。将“fs”与“fs.promises”分开导入可能很重要。 (4认同)
  • 获得 Buffer 后,您可以使用 Buffer 的方法 `toString()` (如 `bufferData.toString()`)将其转换为字符串 - 请参阅 [Buffer 文档](https://www.w3schools.com/nodejs/ met_buffer_tostring.asp)。 (4认同)
  • 截至 2019 年 10 月 21 日,v12 是活跃的 LTS 版本 (3认同)

HKT*_*Lee 40

这是@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);
}
Run Code Online (Sandbox Code Playgroud)


小智 27

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您只想使用 Promise,您可以执行类似 `const fs = require('fs').promises` 的操作 (2认同)
  • 对于导入,您可以执行“import {promise} from“fs”” (2认同)

Non*_*714 14

为了保持简洁并保留以下所有功能fs

const fs = require('fs');
const fsPromises = fs.promises;

async function loadMonoCounter() {
    const data = await fsPromises.readFile('monolitic.txt', 'binary');
    return new Buffer(data);
}
Run Code Online (Sandbox Code Playgroud)

导入fsfs.promises单独导入将提供对整个fsAPI 的访问,同时还保持它的可读性......这样下一个示例就可以轻松完成。

// the 'next example'
fsPromises.access('monolitic.txt', fs.constants.R_OK | fs.constants.W_OK)
    .then(() => console.log('can access'))
    .catch(() => console.error('cannot access'));
Run Code Online (Sandbox Code Playgroud)


Shl*_*rtz 5

您可以像这样用promise轻松包装readFile命令:

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

然后使用:

await readFile("path/to/file");
Run Code Online (Sandbox Code Playgroud)

  • 您缺少“if (err)”路径的返回。 (3认同)

Geo*_*den 5

有一个fs.readFileSync( path, options )方法,它是同步的。


MOS*_*OSI 5

从节点 v14.0.0

const {readFile} = require('fs/promises');

const myFunction = async()=>{
    const result = await readFile('monolitic.txt','binary')
    console.log(result)
}

myFunction()
Run Code Online (Sandbox Code Playgroud)