在node.js中使用带有async / await的文件系统

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在node.js中使用带有async / await的文件系统相关的知识,希望对你有一定的参考价值。

我想在一些文件系统操作中使用async / await。通常async / await工作正常,因为我使用babel-plugin-syntax-async-functions

但是使用这段代码我遇到了names未定义的if情况:

import fs from 'fs';

async function myF() 
  let names;
  try 
    names = await fs.readdir('path/to/dir');
   catch (e) 
    console.log('e', e);
  
  if (names === undefined) 
    console.log('undefined');
   else 
    console.log('First Name', names[0]);
  


myF();

当我将代码重建到回调地狱版本时,一切正常,我得到了文件名。谢谢你的提示。

答案

从节点8.0.0开始,您可以使用:

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

const readdir = util.promisify(fs.readdir);

async function myF() 
  let names;
  try 
    err, names = await readdir('path/to/dir');
    if (err) 
        // Handle the error.
    
   catch (e) 
    console.log('e', e);
  
  if (names === undefined) 
    console.log('undefined');
   else 
    console.log('First Name', names[0]);
  


myF();

https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original

另一答案

Node.js 8.0.0

原生异步/等待

Promisify

从这个版本,您可以使用util库中的本机Node.js函数。

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

const readFileAsync = promisify(fs.readFile)
const writeFileAsync = promisify(fs.writeFile)

const run = async () => 
  const res = await readFileAsync('./data.json')
  console.log(res)


run()


Promise Wrapping

const fs = require('fs')

const readFile = (path, opts = 'utf8') =>
  new Promise((resolve, reject) => 
    fs.readFile(path, opts, (err, data) => 
      if (err) reject(err)
      else resolve(data)
    )
  )

const writeFile = (path, data, opts = 'utf8') =>
  new Promise((resolve, reject) => 
    fs.writeFile(path, data, opts, (err) => 
      if (err) reject(err)
      else resolve()
    )
  )

module.exports = 
  readFile,
  writeFile


...


// in some file, with imported functions above
// in async block
const run = async () => 
  const res = await readFile('./data.json')
  console.log(res)


run()

Advice

如果您不想重新抛出异常上层,请始终使用try..catch来等待块。

另一答案

您可能会产生错误的行为,因为File-Api fs.readdir不会返回承诺。它只需要一个回调。如果你想使用async-await语法,你可以'promisify'这个函数:

function readdirAsync(path) 
  return new Promise(function (resolve, reject) 
    fs.readdir(path, function (error, result) 
      if (error) 
        reject(error);
       else 
        resolve(result);
      
    );
  );

并改为称之为:

names = await readdirAsync('path/to/dir');
另一答案

Native async await style fs functions since version 11

自Node.JS 11.0.0(稳定版)和10.0.0版(实验版)以来,您可以访问已经实现的文件系统方法,并且可以将它们与try catch异常处理一起使用,而不是检查回调是否返回值包含错误。

API非常干净优雅!只需使用.promises对象的fs成员:

import fs from 'fs';
const fsPromises = fs.promises;

async function listDir() 
  try 
    return await fsPromises.readdir('path/to/dir');
   catch (err) 
    console.error('Error occured while reading directory!', err);
  


listDir();
另一答案

这对我有用:

const fsp = require('fs-promise');

(async () => 
  try 
    const names = await fsp.readdir('path/to/dir');
    console.log(names[0]);
   catch (e) 
    console.log('error: ', e);
  
)();

harmony flag启用时,此代码在没有babel的节点7.6中工作:node --harmony my-script.js。从节点7.7开始,you don't even need this flag

包含在开头的fsp库只是fs(和fs-ext)的一个有保证的包装器。

这些天我真的已经离开了没有babel的节点你可以做什么!本土的async / await使编写代码非常愉快!

更新2017-06:fs-promise模块已弃用。使用fs-extra代替相同的API。

另一答案

与自定义函数相比,建议使用https://github.com/davetemplin/async-file等npm包。例如:

import * as fs from 'async-file';

await fs.rename('/tmp/hello', '/tmp/world');
await fs.appendFile('message.txt', 'data to append');
await fs.access('/etc/passd', fs.constants.R_OK | fs.constants.W_OK);

var stats = await fs.stat('/tmp/hello', '/tmp/world');

其他答案已过时

另一答案

我有这个小帮助模块,可以导出promisified版本的fs函数

const fs = require("fs");
const promisify = require("util")

module.exports = 
  readdir: promisify(fs.readdir),
  readFile: promisify(fs.readFile),
  writeFile: promisify(fs.writeFile)
  // etc...
;

以上是关于在node.js中使用带有async / await的文件系统的主要内容,如果未能解决你的问题,请参考以下文章

async/await 会阻塞事件循环吗? [复制]

node.js async/await 与 MySQL 一起使用

Node.js assert.throws 带有异步函数(Promises)

转学习使用 Node.js 中 async-hooks 模块

在 Node.js 中使用 async/await 正确处理错误

Node.js 中 For 循环中的 async.waterfall