Node.js изменения, внесенные в файлы, не отражаются до второго запуска

Я конвертирую все файлы .png в файлы .jpg в каталоге, а затем выполняю некоторые манипуляции с ними, которые могут относиться только к файлам jpeg. Но node.js, похоже, не замечает преобразованные файлы и удаленные файлы png, пока я снова не запустил тот же сценарий.

    const fs = require('fs')
    const pngToJpeg = require('png-to-jpeg');

    let dirrCont = fs.readdirSync( dir );

    files = dirrCont.filter( ( elm ) => /.*\.(png|jpg)/gi.test(elm) );


    for (i in files)
    {  
        let file = files[i]
        let file_name_without_ext = file.replace(/\.[^/.]+$/, "")
        let extension = file.match(/\.[^/.]+$/)
        if (extension[0] == '.png')
        {
            console.info('found')
            let buffer = fs.readFileSync(dir+file);
            pngToJpeg({quality: 100})(buffer)
            .then(output => fs.writeFileSync(dir+file_name_without_ext+'.jpg', output));
            fs.unlinkSync(dir+file)
            extension = '.jpg'
        }
        let target_file = target + file_name_without_ext + '.' + suffix  + extension

    // do some manipulations on dir+file_name_without_ext+extension

Я всегда получаю сообщение об ошибке, что новые файлы jpg не найдены, поэтому манипуляции не работают, хотя файлы png преобразуются в файлы jpg. Когда я снова запускаю тот же сценарий, поскольку теперь все файлы являются jpeg, на этот раз выполняются манипуляции с файлами.

РЕДАКТИРОВАТЬ

как было предложено в одном из ответов @CertainPerformance Я изменил код, чтобы делать большую часть моих вещей внутри блока then, но снова получил ту же ошибку

for (i in files)
{  
    let file = files[i]
    let file_name_without_ext = file.replace(/\.[^/.]+$/, "")
    let extension = file.match(/\.[^/.]+$/)
    if (extension[0] == '.png')
    {
        console.info('found')
        let buffer = fs.readFileSync(dir+file);
        pngToJpeg({quality: 100})(buffer)
        .then(output => {
        fs.writeFileSync(dir+file_name_without_ext+'.jpg', output);
        extension = '.jpg'

        //
        let target_file = target + file_name_without_ext + '.' + suffix  + extension
        // Do some manipulations
        // I am done with the manipulations and I now want to delete
        // the jpg file I just created
        fs.unlinkSync(dir+file_name_without_ext+'.jpg') // Gives me back the same error
        });
    } 

ПРИМЕЧАНИЕ: В редактировании есть небольшие изменения, и я удаляю файл jpg вместо файла png (что я делал изначально)

Чтобы начать отладку, вы можете проверить, что происходит, когда вы вызываете unlinkSync сразу после writeFileSync, чтобы немного упростить дело. Интересно, действительно ли файлы, созданные с помощью writeFileSync, создаются немедленно, или требуется несколько миллисекунд, чтобы они стали видимыми и с которыми можно было работать. (может попробовать поставить короткий setTimeout, посмотрим, что получится?)

CertainPerformance 07.07.2018 03:05

@CertainPerformance выполняемых мною манипуляций, я использую библиотеку jimp, и для этого обязательно должен присутствовать файл

J. Doe 07.07.2018 03:07

@CertainPerformance, но тайм-аут работает

J. Doe 07.07.2018 03:13

Поскольку библиотека требует, чтобы файл присутствовал, но ошибка возникает, когда вы вызываете unlinkSync позже, похоже, что код, вызывающий проблему, находится где-то в вашем Do some manipulations - возможно, файл удаляется внутри него, поэтому unlinkSync затем не работает. unlinkSyncдолжен работают, даже если сразу после writeFileSync.

CertainPerformance 07.07.2018 04:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
2
4
85
1

Ответы 1

Как вы можете видеть по .then, pngToJpeg является асинхронным - если вы хотите работать с dir+file_name_without_ext, вы должны сначала дождаться разрешения исходных .then и writeFileSync. Все, что зависит от асинхронных операций, поместите внутрь then. Например:

if (extension[0] == '.png') {
  console.info('found');
  const buffer = fs.readFileSync(dir + file);
  pngToJpeg({ quality: 100 })(buffer)
    .then(output => {
      fs.unlinkSync(dir + file);
      fs.writeFileSync(dir + file_name_without_ext + '.jpg', output);
      extension = '.jpg';
      const target_file = target + file_name_without_ext + '.' + suffix + extension;
      // do some manipulations on dir+file_name_without_ext+extension
    });
}

(Вы также должны позаботиться о том, чтобы неявно создавать глобальные переменные. Например, используйте вместо этого for (const i in files) или, возможно, for (const file of files), чтобы не возиться с неважными показателями)

Хороший совет. Не могли бы вы объяснить вторую часть, почему было бы лучше использовать for (const file in files) или for (const file of files) и каковы различия между ними?

mmenschig 07.07.2018 02:16

Когда у вас есть массив, for..of будет перебирать значения массива, тогда как for..in перебирает индикаторы массива. Если вы используете только значения массива и заботитесь только об индикаторах, чтобы получить значения, используйте вместо них for..of. (Или, что еще лучше, используйте метод массива, такой как forEach)

CertainPerformance 07.07.2018 02:17

Это восхитительно. Спасибо за объяснение, я никогда не знал

mmenschig 07.07.2018 02:26

Я добавил РЕДАКТИРОВАТЬ к вопросу, ваше решение помогло мне, но не полностью, все еще происходит что-то, чего я не понимаю, и удаление файла jpg обратно внутри then снова дает мне ошибку файл не найден

J. Doe 07.07.2018 02:45

точнее (node:98477) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory,

J. Doe 07.07.2018 02:54

Другие вопросы по теме