Файл переименован перед созданием - PullRequest
0 голосов
/ 06 октября 2019

Я только начал изучать Node.js и сразу же набрал следующий код:

const fs = require(`fs`);

fs.appendFile(`mynewfile1.txt`, `Hello content!`, err => {
  if (err) throw err;
  console.log(`Saved!`);
});

fs.rename(`mynewfile1.txt`, `myrenamedfile.txt`, err => {
  if (err) throw err;
  console.log(`File Renamed!`);
});

Он находится в app.js & , в этом каталоге нет других файлов перед запуском.

Когда я запускаю его (с помощью команды node app.js bash), он стабильно выводит:

> File Renamed!
> Saved!

Я понимаю, что обе операции выполняются асинхронно& Я предполагаю, что переименование файла должно быть быстрее, чем создание нового, но fs.rename должен выдавать, если файл, который мы пытаемся переименовать, не существует и хорошо, он делает, если нет первого оператора. В противном случае он делает вид, что все в порядке.

Я предполагаю, что это происходит потому, что перед выполнением дорогостоящего узла ввода / вывода каким-то образом оценивает операции и, в моем случае, вместо создания нового файла и переименования его, просто создаетфайл с именем myrenamedfile.txt сразу.

Мои вопросы:

  1. Я прав в своем последнем предположении? Если да, то не могли бы вы указать на некоторую документацию, касающуюся этого, в противном случае, не могли бы вы объяснить, почему это происходит?
  2. Не могли бы вы также указать мне правила, которые регулируют поведение fs.rename в этом случае? Я имею в виду, что он явно не переименовывает существующий файл (потому что он еще не создан), он должен делать что-то другое. Итак, где находится документация для этого «чего-то другого»? Основная документация не указывает ее.

UPD:

Большое спасибо всем приятным людям, которые ответили до сих пор, я знаю, что либоpromisify из utils модуля или экспериментального require('fs').promises можно использовать для цепочки операций, если это необходимо, но возникает вопрос , почему код работает и не выдает ошибку, а не как операции могут быть связаны друг с другом.

Ответы [ 3 ]

1 голос
/ 06 октября 2019

Да, ваше предположение об асинхронном потоке верно. Поскольку файл изначально отсутствует и rename запускается независимо от того, завершен appendFile или нет, он выдаст ошибку как no such file or directory.

. консоль показывает: File Renamed!, потому что вы только что распечатали его без каких-либо условий.

Для обработки этого сценария либо используйте соответствующие методы синхронизации , например:

const fs = require(`fs`);

fs.appendFileSync(`mynewfile1.txt`, `Hello content!`);
console.log(`Saved!`);

fs.renameSync(`mynewfile1.txt`, `myrenamedfile.txt`);
console.log(`File Renamed!`);

Илииспользуйте async / await :

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

const appendAndRename = async () => {
    try {
        await util.promisify(fs.appendFile)(`mynewfile1.txt`, `Hello content!`);
        console.log(`Saved!`);

        await util.promisify(fs.rename)(`mynewfile1.txt`, `myrenamedfile.txt`);
        console.log(`File Renamed!`);
    } catch(err) {
        console.log(err);
        throw err;
    }
}

appendAndRename();

Убедитесь, что ваши операторы await всегда заключены в блок try / catch и непосредственную родительскую функциюобъявляется с ключевым словом async .

Надеюсь, это поможет:)

1 голос
/ 06 октября 2019

Найдите рабочий (проверенный) фрагмент кода ниже. Использовал встроенный модуль 'util' для обещания функций fs.

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

    async function doTheOpAsync() {
        const appendFile = util.promisify(fs.appendFile);
        const rename = util.promisify(fs.rename);
        try{
            await appendFile(`mynewfile1.txt`, `Hello content!`);
            console.log(`Saved!`);
            await rename(`mynewfile1.txt`, `myrenamedfile.txt`);
            console.log(`File Renamed!`);
        }catch(ex){
            console.log(ex);
        }
    }
    doTheOpAsync();
1 голос
/ 06 октября 2019

В случае "Файл переименован!"выполняется первым, "Сохранено!"Part создаст новый файл с именем mynewfile1.txt

. Если вы хотите сохранить порядок, используйте в асинхронной функции:

const fs = require(`fs`);

await fs.appendFile(`mynewfile1.txt`, `Hello content!`);
console.log(`Saved!`);

await fs.rename(`mynewfile1.txt`, `myrenamedfile.txt`);
console.log(`File Renamed!`);
...