Dropbox JS SDK: выполнить i++ внутри.then-функции
Я с трудом назвал этот вопрос, но постараюсь объяснить его довольно быстро.
Я использую Dropbox JavaScript SDK для получения общих ссылок из определенных папок. Прежде всего, я использую следующий код для извлечения файлов из папки:
var DROPBOX_PATH = path;
var ACCESS_TOKEN = '***';
var dbx = new Dropbox({ accessToken: ACCESS_TOKEN });
function listFiles() {
dbx.filesListFolder({ path: DROPBOX_PATH })
.then(function(response) {
displayFiles(response.entries);
})
.catch(function(error) {
console.error(error);
});
return false;
}
Затем я переберу эти файлы для использования dbx.sharingGetSharedLinks()
, dbx.filesGetTemporaryLink()
так же как dbx.sharingGetSharedLinkFile()
и получите их ссылки. Дело в том, что этот процесс может занять некоторое время, если папка содержит пару файлов, и я хочу использовать <progress>
элемент, чтобы показать, как далеко продвинулся прогресс.
Во-первых, я пытался использовать for(var i = 0; i < files.length; i++)
цикл, чтобы обернуть три функции, упомянутые выше, и добавить i
прогрессировать значение бара под dbx.sharingGetSharedLinkFile()
"s .then()
процесс, но они не синхронизированы - i
значение увеличивается до того, как все эти функции достигнут своих соответствующих целей и могут выводить что угодно.
Я попытался вместо этого заменить его while()
цикл и положить i++
внутри последней функции dbx, но это просто заставляет мой веб-браузер перегружаться и, возможно, оказаться в бесконечном цикле.
Есть ли способ получить i
увеличение стоимости в соответствии с dbx.sharingGetSharedLinkFile().then()
?
2 ответа
Ваш код действительно грязный. Если вы можете использовать ES6, или q
библиотека. Просто используйте обещания, как это.
var promises = [];
files.forEach((file) => {
promises.push(sharingGetSharedLinks(file_path).then(filesGetTemporaryLink(download_path)).then(sharingGetSharedLinkFile(download_url)));
});
Promise.all(promises).then((values) => {
// values are, an array of responses where each response is the three requests per each file
});
Отдельная логика для каждого запроса sharingGetSharedLinks
возвращает результат для этого запроса и обрабатывает его, filesGetTemporaryLink
сделать то же самое с результатом sharingGetSharedLinks
и сделайте новый http-запрос, затем последний повторите процесс, но с результатом filesGetTemporaryLink
,
Тогда вы должны быть в состоянии обрабатывать все запросы вместе. [r1, r2, ...]
где r1 включает в себя процесс запроса на разделение GetSharedLinks, filesGetTeditionalLink и sharedGetSharedLinkFile.
Но вы должны провести рефакторинг всего своего кода, здесь очень просто использовать обещания https://www.promisejs.org/patterns/
Для достижения ожидаемого поведения вам нужно выполнить итерацию, используя функцию вместо цикла.
Ваш текущий код не будет работать, как ожидалось, потому что обратный вызов метода API Dropbox sharingGetSharedLinks
будет выполняться только после того, как будет выполнен асинхронный запрос к серверу dropbox (внутри этого метода), в то время как основной цикл продолжит итерацию по списку файлов.
Наконец, речь идет об обещаниях, поэтому я попытаюсь указать вам правильное направление с помощью этой ссылки MDN об обещаниях и небольшого примера кода:
function displayFiles(files) {
//... your code
// i'll show you only changes
var i = 0;
(function listNextFile(){
let file = files[i]
if (file) {
var name = file.name.slice(4).slice(0, -7).replace('_', '/'),
file_path = file.path_display;
dbx.sharingGetSharedLinks({ path : file_path }).then(function(response){
// ...
// there is your code
// after all you need to icrease counter and call function again
i++
listNextFile();
});
}
})()
}