Ich möchte async/await bei einigen Dateisystemvorgängen verwenden. Normalerweise funktioniert async/await gut, da ich babel-plugin-syntax-async-functions
verwende.
Aber mit diesem Code stoße ich in den Falls-Fall, in dem names
nicht definiert ist:
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();
Wenn ich den Code in die Callback-Höllenversion umwandle, ist alles in Ordnung und ich bekomme die Dateinamen.
Ab Knoten 8.0.0 können Sie Folgendes verwenden:
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();
Siehe https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original
Möglicherweise führt dies zu einem falschen Verhalten, da der Datei-Api fs.readdir
kein Versprechen zurückgibt. Es braucht nur einen Rückruf. Wenn Sie die async-await-Syntax verwenden möchten, können Sie die Funktion folgendermaßen "versprechen":
function readdirAsync(path) {
return new Promise(function (resolve, reject) {
fs.readdir(path, function (error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
und nenne es stattdessen:
names = await readdirAsync('path/to/dir');
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
}
Verwenden Sie immer try..catch
für Aufwarteblöcke, wenn Sie die Ausnahme nicht erneut starten möchten.
// in some module, with imported function
// in async block
const res = await readFile('data.json')
console.log(res)
Seit Node.JS 10.0.0 haben Sie Zugriff auf Dateisystemmethoden, die bereits bekanntgegeben wurden. Sie können sie mit try catch
-Ausnahmebehandlung verwenden, anstatt zu prüfen, ob der Rückgabewert einen Fehler enthält.
Die API ist experimentell , aber sie ist sehr sauber und elegant! Verwenden Sie einfach .promises
member von fs
object:
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();
Folgendes hat für mich funktioniert:
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);
}
})();
Dieser Code funktioniert in Knoten 7.6 ohne Babel, wenn Harmony-Flag aktiviert ist: node --harmony my-script.js
. Und beginnend mit Knoten 7.7, Sie brauchen dieses Flag nicht einmal !
Die fsp
Bibliothek, die am Anfang enthalten ist, ist nur ein versprochener Wrapper für fs
(und fs-ext
).
Ich bin wirklich begeistert davon, was man heutzutage in node ohne babel machen kann! Native async
await
macht das Schreiben von Code zum Vergnügen!
_/UPDATE 2017-06: Das Modul fs-promise wurde nicht mehr unterstützt. Verwenden Sie stattdessen fs-extra
mit derselben API.
Empfehlen Sie die Verwendung eines npm-Pakets wie https://github.com/davetemplin/async-file im Vergleich zu benutzerdefinierten Funktionen. Zum Beispiel:
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');
Andere Antworten sind veraltet
Ich habe dieses kleine Hilfemodul, das versprochene Versionen von fs
Funktionen exportiert
const fs = require("fs");
const {promisify} = require("util")
module.exports = {
readdir: promisify(fs.readdir),
readFile: promisify(fs.readFile),
writeFile: promisify(fs.writeFile)
// etc...
};