2017-02-08 21 views
0

У меня возникла проблема с fs.writeFile() и Promise.all.Ошибка: файл не найден только для одного обещания с обещанием.all и ssh2-sftp-client

У меня есть сценарий, который берет файл из dropbox, сохраняет его на сервере и отправляет его нескольким SFTP, чтобы они могли его использовать. Проблема в том, что у меня всегда есть одно из моих обещаний, которое вызывает ошибку, говоря, что файл не существует. Я подозреваю, что проблема с aynscrhonous процессом, но я не могу понять, что я сделал неправильно.

Я использую пакеты ssh2-sftp-client и fs.

Вы найдете ниже выпиской моего кода:

//I just got the dropboxfile with promise 
.then(function(data) { 
    myDownloadedFile = data.name 
    return new Promise((res,rej) => { 
      fs.writeFile(myDownloadedFile, data.fileBinary, 'binary', function (err) { 
       if (err) { 
        throw err 
        rej("file not saved") 
       } else { 
        log.info('File save : ' + data.name) 
        res() 
       } 
      }) 
     }) 
    }) 
    //FTP sending 
    .then(function() { 
     return Promise.all([sendFiletoFTP(myConnection1, "partner1"), sendFiletoFTP(myConnection2, "partner2"), sendFiletoFTP(myConnection3, "partner3")]) 
    }) 

И ниже функции sendFiletoFTP:

var sendFiletoFTP = function(FTPObj, myPartenaire) { 
    return new Promise((res,rej) => { 
     let sftp = new Client(); 
     sftp.connect(FTPObj).then(() => { 
      return sftp.put(myDownloadedFile, myDownloadedFile) 
     }) 
     .then((data) => { 
      sftp.end() 
     }) 
     .then(() => { 
      log.info("OK pour " + myPartenaire + " : " + myDownloadedFile); 
      res() 
     }) 
     .catch((error) => { 
      rej(error) 
     }) 
    }) 
} 

Ошибка у меня есть: Ошибка: Файл не найден, который срабатывает при SFTP. put() действие.

У вас есть какие-либо идеи о том, что может быть неправильным?

+0

Я не вижу, что вызывает ошибку, но, пожалуйста, не «бросайте» в обратный вызов конструктора обещаний: хотя это работает в вашем случае, вы никогда не выполняете ' REJ() '. Лучше оставить «бросок» и сделать «rej()». Кроме того, вашей второй функции не нужно создавать новые обещания. Просто верните цепочку 'sftp.connect() .then() .then()' без вызова 'res' и без' catch'. – trincot

+1

'myDownloadedFile' выглядит глобально (или должен существовать в области, охватывающей оба фрагмента кода), поэтому что-то * может быть сбито до начала отправки? ... почему бы не изменить 'sendFiletoFTP', чтобы принять имя файла' var sendFiletoFTP = function (FTPObj, myPartenaire, filename) {', а затем вызвать как' sendFiletoFTP (myConnection1, "partner1", myDownloadedFile), ... ' –

ответ

0

Примечание: ваш первый фрагмент, кажется, имеет комбинацию стрелок и регулярных функций без видимых причин! Почему бы не использовать функции курсора в любом месте они соответствующий

myDownloadedFile выглядит глобальной (или должны существовать в области, которая охватывает как фрагменты кода), так что что-то может быть затирания его перед отправкой отделки?

Теперь, путем пропускания filename функции sendFiletoFTP, вы можете обеспечить некоторые глобальные не получить «затирается» до того, как асинхронная материал заканчивает - что то, что я подозреваю, что происходит, но, не видя всех соответствующих кода, это всего лишь предположение. В приведенном ниже коде, первый Promise разрешен к data.name, устраняет необходимость в какой-либо вар, потому что имя является аргументом в .then, что запускает процесс FTP

Перепишите первый фрагмент следующим образом:

.then(data => new Promise((res,rej) => 
    fs.writeFile(myDownloadedFile, data.fileBinary, 'binary', err => { 
     if (err) { 
      rej("file not saved"); 
     } else { 
      log.info('File save : ' + data.name); 
      res(data.name); 
     } 
    }) 
)) 
//FTP sending 
.then(filename => Promise.all([ 
     sendFiletoFTP(myConnection1, "partner1", filename), 
     sendFiletoFTP(myConnection2, "partner2", filename), 
     sendFiletoFTP(myConnection3, "partner3", filename) 
    ]) 
); 

sendFiletoFTP не нуждается в новом конструкторе Promise, так как Client(). Connect возвращает обещание уже. Добавляя дополнительный аргумент, тогда функция становится

var sendFiletoFTP = function (FTPObj, myPartenaire, myDownloadedFile) { 
    return new Client().connect(FTPObj) 
    .then(() => sftp.put(myDownloadedFile, myDownloadedFile)) 
    .then(data => sftp.end()) 
    .then(() => log.info("OK pour " + myPartenaire + " : " + myDownloadedFile)); 
};