У меня есть следующая функция. Он вызывает себя повторно и выполняет итерации через ftp-серверы, проверяя наличие новых файлов. Я пытаюсь сделать это обещанием, чтобы я мог operate().then(function(newFilesObject)
, но я не могу получить .then
для активации. Он пытается ее разрешить, но не передает. Кстати, newFiles - это глобальная переменная, которая получает файлы на каждый сервер, присоединенный к ней. Если требуется больше кода, я могу опубликовать его или опубликовать.Обещание не возвращается должным образом
ответ
Обещания в образце кода не возвращаются, так как их резольверы или отклонители не всегда вызываются. Фактически, resolve
вызывается только тогда, когда i === 0
. Согласно Promises/A+ specification, обещания могут быть преобразованы только в состояние fulfilled
путем вызова resolve
. Он также может быть преобразован только в состояние rejected
путем вызова reject
или исключения исключения изнутри исполнителя. Таким образом, достижение конца исполнителя без вызова или передачи одного в качестве обратного вызова гарантирует, что обещание остается в pending
состоянии неопределенно долго.
Цель, которую вы ищете, может быть достигнута с помощью небольшого рефакторинга. Учитывая следующее в качестве цели:
- последовательно через каждый FTP-сервер ...
- Прочитайте данный каталог для списка файлов
- Сравнить список файлов в один хранится локально, чтобы определить новые
- Если есть новые, загружать их последовательно
- Возвращает список всех недавно загруженных файлов
данных
var knownFTPServers = [{
'localDirectory': 'sub/',
'localFilepaths': ['docA.json', 'docB.json'],
'remoteDirectory': 'remsub/',
'remoteFilepaths': [],
'jsftpHandle': undefined,
'host': 'example.com'
},
{
'localDirectory': 'root/',
'localFilepaths': ['file1.txt', 'file2.txt'],
'remoteDirectory': 'remroot/',
'remoteFilepaths': [],
'jsftpHandle': undefined,
'host': 'geocities.com'
}];
Logic
function pullNewFilesFromFTPServer(ftpServer) {
return new Promise(function (resolve, reject) {
var handle = new JSFtp(ftpServer);
ftpServer.jsftpHandle = new JSFtp(ftpServer);
// Returns a promise for reading a directory from JSFtp server
// resolves with file list
// rejects with FTP error
function readdir(directory) {
return new Promise(function (resolve, reject) {
handle.ls(ftpServer.remoteDirectory, function (err, res) {
if (err) return reject(err);
resolve(res);
});
});
}
// Returns a promise for downloading a file from a remote JSFtp server
// resolves with the filepath of the downloaded filepath
// rejects with FTP error
function downloadFile(path) {
return new Promise(function (resolve, reject) {
handle.get(path, path, function (err) {
if (err) return reject(err);
resolve(path);
});
});
}
// get all remote filepaths on server
readdir(ftpServer.remoteDirectory)
// filter out filepaths already present locally
.then(function (remoteFilepaths) {
return remoteFilepaths.filter(function (path) {
return ftpServer.localFilepaths.indexOf(path) < 0;
});
})
// download new filepaths sequentially
// reduce turns the array of new filepaths into a promise chain
// return new filepaths after completing the promise chain
.then(function (newFilepaths) {
return newFilepaths.reduce(function (previousDownloadPromise, newPath) {
return previousDownloadPromise.then(function() {
return downloadFile(newPath);
});
}, Promise.resolve())
.then(function() { return newFilepaths; });
})
// resolve server promise with new filepaths or reject with errors
.then(resolve, reject);
});
}
var allFilesDownloaded = [];
knownFTPServers.reduce(function (previousServerPromise, server) {
return previousServerPromise.then(function (filesDownloaded) {
allFilesDownloaded = allFilesDownloaded.concat(filesDownloaded);
return pullNewFilesFromFTPServer(server);
});
}, Promise.resolve([]))
.then(function() {
console.log(allFilesDownloaded);
}, function (err) {
console.err(err);
});
Хотя это может показаться немного более сложным в некоторых местах действия каждой функции являются более модульным. Идея, которая несколько неинтуитивно, использует Array.prototype.reduce
, чтобы превратить массив данных в массив обещаний, выполняемых последовательно.
С момента создания обещания загрузить файл пытается сразу загрузить файл, невозможно сразу же создать все обещания, если вы хотите загрузить их по одному. В противном случае последовательность может выглядеть несколько проще.
- 1. Обещание не работает должным образом
- 2. angularjs обещание не разрешается должным образом
- 3. Угловое обещание задержки не работает должным образом
- 4. Обещание не возвращается?
- 5. Java Resultset.getInt() не возвращается должным образом?
- 6. Функция ARM не возвращается должным образом
- 7. Рекурсивная функция VBA не возвращается должным образом
- 8. Закрытая переменная не возвращается должным образом
- 9. Отклонение и обещание в angularjs не работает должным образом
- 10. Запрос поисковой системы Google Maps Store не возвращается должным образом
- 11. JSON строка не возвращается должным образом в JSP
- 12. Проблема с Facebook Api login $ пользователь не возвращается должным образом
- 13. Выбор Java Выбранный индекс не возвращается должным образом
- 14. Почему этот массив не возвращается должным образом из класса JavaScript?
- 15. Workbench на Drupal 7 не возвращается в проект должным образом
- 16. Функция C++ не возвращается должным образом: строковый деструктор называется
- 17. iOS - Динамический размер метки не возвращается должным образом
- 18. Значение индекса списка Python не возвращается должным образом
- 19. clearTimeout() не работает должным образом
- 20. Может ли адаптация адаптера жасмина должным образом ждать protractor.promise.defer(). Обещание?
- 21. Time.use_zone не работает должным образом
- 22. Ограничения не работают должным образом
- 23. Собственные обещания Promisekit не отвечают должным образом
- 24. BETWEEN не работает должным образом
- 25. db.put() не работает должным образом
- 26. ngif не работает должным образом
- 27. ResponsiveSlide.js не работает должным образом
- 28. обещание mongoDB возвращается слишком рано
- 29. угловой $ http обещание возвращается дважды
- 30. : не работает должным образом
Посмотрите на внутренние вызовы 'operation()'. Операция возвращает обещание, но вы ничего не делаете с ним. –
Это именно так, что я снова могу повторить сервер, если вы понимаете, что я говорю. если он закончился (как проверено в начале), он разрешает. Что я могу сделать с этим? note: https://github.com/dkran/FloorCoveringEDI/blob/combinator/app.js – dkran
Давайте ставим его по-другому: если 'if (servers [i])' is 'true', вы никогда не вызываете' resolve'. Может быть, вы хотите решить после того, как обещание, возвращаемое внутренним вызовом 'operation()' разрешает? –