いくつかのファイルシステム操作でasync/awaitを使いたいのですが。私はbabel-plugin-syntax-async-functions
を使っているので、通常async/awaitはうまく動きます。
しかし、このコードで私は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以降では、これを使用できます。
import fs from 'fs';
import {promisify} from 'util';
const readdir = 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 をご覧ください。
このバージョンから、tilライブラリのネイティブ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()
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()
例外の上限を再スローしたくない場合は、常に待機ブロックにtry..catch
を使用してください。
File-Api fs.readdir
は約束を返さないため、間違った動作をする可能性があります。それはコールバックだけを取ります。 async-awaitの構文を使いたいのであれば、このような機能を「約束」することができます。
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');
Node.JS 11.0.0(安定版)、およびバージョン10.0.0(実験的)以降は、既に確認されているファイルシステムメソッドにアクセスでき、コールバックの戻り値を確認するのではなくtry catch
例外処理を使用して使用できますエラーが含まれています。
APIはとてもきれいでエレガントです! fs
オブジェクトの.promises
メンバーを使用するだけです。
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);
}
})();
ハーモニーフラグ が有効な場合、このコードはbabelなしでノード7.6で機能します:node --harmony my-script.js
。そしてノード7.7から始まって、 あなたはこのフラグさえ必要としません !
冒頭に含まれている fsp
ライブラリーは、fs
(および fs-ext
)の単なるラッパーです。
最近私はあなたがばかにならずにnodeでできることについて本当に去りました!ネイティブのasync
/await
は、コードを書くのをとても楽しいものにします。
更新2017-06:fs-promiseモジュールは廃止予定です。同じAPIで代わりに fs-extra
を使用してください。
カスタム関数と比較して、 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');
他の回答は古くなっています
私はエクスポートするこの小さな助けモジュールを持っています 約束された バージョンのfs
関数
const fs = require("fs");
const {promisify} = require("util")
module.exports = {
readdir: promisify(fs.readdir),
readFile: promisify(fs.readFile),
writeFile: promisify(fs.writeFile)
// etc...
};