Я конвертирую все файлы .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 (что я делал изначально)
@CertainPerformance выполняемых мною манипуляций, я использую библиотеку jimp, и для этого обязательно должен присутствовать файл
@CertainPerformance, но тайм-аут работает
Поскольку библиотека требует, чтобы файл присутствовал, но ошибка возникает, когда вы вызываете unlinkSync позже, похоже, что код, вызывающий проблему, находится где-то в вашем Do some manipulations - возможно, файл удаляется внутри него, поэтому unlinkSync затем не работает. unlinkSyncдолжен работают, даже если сразу после writeFileSync.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Как вы можете видеть по .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) и каковы различия между ними?
Когда у вас есть массив, for..of будет перебирать значения массива, тогда как for..in перебирает индикаторы массива. Если вы используете только значения массива и заботитесь только об индикаторах, чтобы получить значения, используйте вместо них for..of. (Или, что еще лучше, используйте метод массива, такой как forEach)
Это восхитительно. Спасибо за объяснение, я никогда не знал
Я добавил РЕДАКТИРОВАТЬ к вопросу, ваше решение помогло мне, но не полностью, все еще происходит что-то, чего я не понимаю, и удаление файла jpg обратно внутри then снова дает мне ошибку файл не найден
точнее (node:98477) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory,
Чтобы начать отладку, вы можете проверить, что происходит, когда вы вызываете
unlinkSyncсразу послеwriteFileSync, чтобы немного упростить дело. Интересно, действительно ли файлы, созданные с помощьюwriteFileSync, создаются немедленно, или требуется несколько миллисекунд, чтобы они стали видимыми и с которыми можно было работать. (может попробовать поставить короткийsetTimeout, посмотрим, что получится?)