Дублирование операций Node-FTP при загрузке файла

Поскольку есть вещи, называемые «ад обратных вызовов». Это был единственный способ получить файл с сервера на мой vps-компьютер и загрузить его. Процесс был прост:

  1. Загрузите файл .json с ftp-сервера
  2. Отредактируйте файл .json на компьютере.
  3. Загрузите файл .json и удалите копию компьютера.

Однако моя проблема заключалась в следующем: хотя он загружается один раз, он возвращает загрузку в зависимости от того, сколько раз я командую им в течение 1 сеанса (команда № 1, делает это один раз, команда № 2, делает это дважды и т. д.).

Я пытался запустить его как императив, но он аннулируется. Пришлось прибегнуть к аду обратных вызовов, чтобы запустить код почти правильно. Триггер работает для инициализации команды, но команда и сеанс не работают.

      ((  //declaring my variables as parameters
    ftp=new (require('ftp'))(),
    fs=require('fs'),
    serverFolder='./Path/Of/Server/',
    localFolder='./Path/Of/Local/',
    file='some.json',
    {log}=console
)=>{
    //run server if its ready
    ftp.on('ready',()=>{

       //collect a list of files from the server folder
       ftp.list(serverFolder+file,(errList,list)=>
           errList|| typeof list === 'object' &&
           list.forEach($file=>

              //if the individual file matches, resume to download the file
              $file.name===file&&(
                 ftp.get(serverFolder+file,(errGet,stream)=>
                     errGet||(
                        log('files matched!  cdarry onto the operation...'),
                        stream.pipe(fs.createReadStream(localFolder+file)),
                        stream.once('close',()=>{

                            //check if the file has a proper size
                            fs.stat(localFolder+file,(errStat,stat)=>
                                errStat || stat.size === 0

                                //will destroy server connection if bytes = 0
                                ?(ftp.destroy(),log('the file has no value'))

                                //uploads if the file has a size, edits, and ships
                                :(editThisFile(),
                                    ftp.put(
                                       fs.createReadStream(localFolder+file),
                                       serverFolder+file,err=>err||(
                                          ftp.end(),log('process is complete!')
                                 ))
                                //editThisFile() is a place-holder editor
                                //edits by path, and object                                    
                            )
                        })
                    )
                 )
              )
           )
       );
    });
    ftp.connect({
       host:'localHost',
       password:'1Forrest1!',
       port:'21',
       keepalive:0,
       debug: console.log.bind(console)
    });
})()

Основная проблема заключается в том, что по какой-то причине он будет возвращать копию команды снова и снова как «перенос».

Редактировать: хотя достоинства «стиля программирования» отличаются от общей мета. Все это приводит к одной и той же проблеме ада обратного вызова. Нужны любые рекомендации. Для удобочитаемости мне помогли отредактировать мой код, чтобы упростить его. Версия с улучшенной читабельностью

1 ответ

The ftpAPI модулей приводит к аду обратного вызова. Он также не поддерживается какое-то время и содержит ошибки. Попробуйте модуль с промисами вродеbasic-ftp.

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

      const ftp = require('basic-ftp')
const fsp = require('fs').promises

async function updateFile(localFile, serverFile){
  const client = new ftp.Client()
  await client.access({
     host: 'localHost',
     password: '1Forrest1!',
  })
  await client.downloadTo(localFile, serverFile)
  const stat = await fsp.stat(localFile)
  if (stat.size === 0) throw new Error('File has no size')
  await editThisFile(localFile)
  await client.uploadFrom(localFile, serverFile)
}

const serverFolder = './Path/Of/Server'
const localFolder = './Path/Of/Local'
const file = 'some.json'
updateFile(localFolder + file, serverFolder + file).catch(console.error)

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