Я столкнулся с проблемой, возможно, это не что-то огромное. Итак, в основном я использую API Google Диска для извлечения файлов с диска, и я хочу сделать разбиение на страницы, мне удалось сделать следующую страницу очень хорошо, но проблема возникла, когда я попытался реализовать кнопку Previous Page. Мне удалось заставить его работать, но теперь, если есть 2 страницы, он работает просто отлично, но если их больше 2, например, если есть 3 страницы, если я перехожу на 3-ю страницу, нажмите кнопку Previous Page, я перехожу на 2-ю страницу , но тогда нет "previousPageToken", поэтому кнопка вообще не появляется. Должен ли я хранить токены в массиве или что-то в этом роде?
Вот код:
let currentPageToken = null;
let previousPageToken = null;
async function listFiles(folderId, pageToken = null) {
$('#table_content').empty();
$('#table_content').remove();
isListFilesInProgress = true; // Set the flag to indicate listFiles() is in progress
// Disable the button during listFiles() execution
$('#show_files_button').prop('disabled', true);
const request = {
q: `'${folderId}' in parents`,
pageSize: 10,
fields: 'nextPageToken, files(id, name, mimeType, thumbnailLink, webContentLink, modifiedTime)',
pageToken: pageToken, // Pass the pageToken to retrieve the next page
};
gapi.client.drive.files
.list(request)
.then(function (response) {
console.info(response);
var files = response.result.files;
if (files && files.length > 0) {
var table = document.createElement('table');
table.classList.add('table', 'table-striped');
table.id = 'table_content';
var thead = document.createElement('thead');
var headerRow = document.createElement('tr');
var header1 = document.createElement('th');
header1.textContent = 'Thumbnail';
var header2 = createSortableHeader('Name', 'name');
var header3 = createSortableHeader('Type', 'mimeType');
var header4 = createSortableHeader('Last Updated', 'modifiedTime');
var header5 = document.createElement('th');
header5.textContent = 'Download';
headerRow.appendChild(header1);
headerRow.appendChild(header2);
headerRow.appendChild(header3);
headerRow.appendChild(header4);
headerRow.appendChild(header5);
thead.appendChild(headerRow);
table.appendChild(thead);
var tbody = document.createElement('tbody');
for (var i = 0; i < files.length; i++) {
(function (file) {
var fileName = file.name;
var mimeType = file.mimeType;
var thumbnailLink = file.thumbnailLink;
var downloadLink = file.webContentLink;
var lastUpdated = new Date(file.modifiedTime).toLocaleString();
var fileId = file.id;
var row = document.createElement('tr');
var thumbnailCell = createThumbnailCell(thumbnailLink, mimeType, fileId);
row.appendChild(thumbnailCell);
var nameCell = document.createElement('td');
nameCell.textContent = fileName;
row.appendChild(nameCell);
var typeCell = document.createElement('td');
typeCell.textContent = mimeType;
row.appendChild(typeCell);
var lastUpdatedCell = document.createElement('td');
lastUpdatedCell.textContent = lastUpdated;
row.appendChild(lastUpdatedCell);
if (mimeType != 'application/vnd.google-apps.folder') {
var downloadCell = document.createElement('td');
var downloadLinkElem = document.createElement('a');
downloadLinkElem.href = downloadLink;
downloadLinkElem.textContent = 'Download';
downloadLinkElem.classList.add('btn', 'btn-primary');
downloadLinkElem.target = '_blank';
downloadCell.appendChild(downloadLinkElem);
row.appendChild(downloadCell);
}
// Add click event listener to navigate into folders
if (mimeType === 'application/vnd.google-apps.folder') {
row.classList.add('folder-row');
row.addEventListener('click', function () {
var folderId = file.id;
listFiles(folderId);
});
}
tbody.appendChild(row);
})(files[i]);
}
table.appendChild(tbody);
document.getElementById('content').appendChild(table);
// Remove existing Next Page and Previous Page buttons
$('.next-page-button').remove();
$('.previous-page-button').remove();
// Add Next Page button if there is a nextPageToken
const nextPageToken = response.result.nextPageToken;
if (nextPageToken) {
const nextPageButton = document.createElement('button');
nextPageButton.textContent = 'Next Page';
nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
nextPageButton.addEventListener('click', function () {
listFiles(folderId, nextPageToken); // Call listFiles() with the nextPageToken
});
document.getElementById('content').appendChild(nextPageButton);
}
// Add Previous Page button if there is a pageToken
if (pageToken) {
const previousPageButton = document.createElement('button');
previousPageButton.textContent = 'Previous Page';
previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
previousPageButton.addEventListener('click', function () {
listFiles(folderId); // Call listFiles() without the pageToken to go back to the previous page
});
document.getElementById('content').appendChild(previousPageButton);
}
}
})
.finally(function () {
isListFilesInProgress = false;
$('#show_files_button').prop('disabled', false);
});
}
Подводя итог, я могу вернуться только на одну страницу назад, и она останавливается там, поэтому я могу нормально перейти на следующую страницу, потому что для следующей страницы всегда есть токен.
Заранее спасибо!
Редактировать:
Итак, как было предложено, я попытался сохранить токены страницы в массиве, я помещаю его в массив, и при следующем вызове функции (при нажатии следующей страницы) токен берется из массива, и я проверял с помощью console.info(), что токен назначен previousPageToken, но по какой-то причине на следующей странице, когда я нажимаю кнопку «Предыдущая страница», теперь просто обновляется та же страница, это код создания кнопки:
const previousPageToken = pageTokens[pageTokens.length - 1];
console.info('next');
console.info(nextPageToken);
console.info('previous');
console.info(previousPageToken);
if (previousPageToken) {
const previousPageButton = document.createElement('button');
previousPageButton.textContent = 'Previous Page';
previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
previousPageButton.addEventListener('click', function () {
listFiles(folderId, previousPageToken); // Call listFiles() with the previousPageToken
});
document.getElementById('content').appendChild(previousPageButton);
}



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


При проверке общей логики того, чего вы пытаетесь достичь, рекомендуемый подход действительно заключается в сохранении nextPageToken в массиве, чтобы его можно было вызвать позже. Теоретически достаточно просто использовать array.push(), это также позволит вам перемещаться по индексу массива, поскольку вы будете точно знать, что новый «nextPageToken» будет добавлен в конец массива. Я могу порекомендовать просмотреть ответ Танайке в этом посте, чтобы использовать его в качестве справки для управления токенами:
async function main(auth) {
const drive = google.drive({ version: "v3", auth });
const fileList = [];
let NextPageToken = "";
do {
const params = {
// q: "", // In this case, this is not required.
orderBy: "name",
pageToken: NextPageToken || "",
pageSize: 1000,
fields: "nextPageToken, files(id, name)",
};
const res = await drive.files.list(params);
Array.prototype.push.apply(fileList, res.data.files);
NextPageToken = res.data.nextPageToken;
} while (NextPageToken);
console.info(fileList.length); // You can see the number of files here.
}
В качестве примечания, имейте в виду, что nextPageTokens недолговечны, согласно моему опыту и опыту других пользователей Stackoverflow (например, Linda Lawton - DaImTo ), они длятся около часа
хранить элементы в массив
Итак, мне наконец удалось решить эту проблему, поэтому я опубликую ответ, может быть, кто-то найдет это полезным. Прежде всего, я использовал массив для хранения токена текущей страницы на каждой странице. При нажатии кнопки «Предыдущая страница» я удаляю последний элемент в массиве. Вот код:
// Add Previous Page button if there is a previousPageToken
var previousPageToken = pageTokens[pageTokens.length - 1];
if (pageTokens.length != 0)
{
if (previousPageToken) {
const previousPageButton = document.createElement('button');
previousPageButton.textContent = 'Previous Page';
previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
previousPageButton.addEventListener('click', function () {
pageTokens = pageTokens.slice(0, -1);
listFiles(folderId, previousPageToken); // Call listFiles() with the previousPageToken
});
document.getElementById('content').appendChild(previousPageButton);
}
else if (previousPageToken == null) {
const previousPageButton = document.createElement('button');
previousPageButton.textContent = 'Previous Page';
previousPageButton.classList.add('btn', 'btn-primary', 'previous-page-button');
previousPageButton.addEventListener('click', function () {
pageTokens = [];
listFiles(folderId); // Call listFiles()
});
document.getElementById('content').appendChild(previousPageButton);
}
}
// Add Next Page button if there is a nextPageToken
const nextPageToken = response.result.nextPageToken;
if (nextPageToken) {
const nextPageButton = document.createElement('button');
nextPageButton.textContent = 'Next Page';
nextPageButton.classList.add('btn', 'btn-primary', 'next-page-button');
nextPageButton.addEventListener('click', function () {
pageTokens.push(pageToken);
listFiles(folderId, nextPageToken); // Call listFiles() with the nextPageToken
});
document.getElementById('content').appendChild(nextPageButton);
}
Затем я понял, что по какой-то причине я не могу получить токен первой страницы (он был сохранен как нуль в массиве). Поэтому я сделал отдельный else if для случая, когда последним элементом в массиве является null, что означало, что это была 2-я страница. Поэтому, когда я вызываю свою функцию без токена страницы, которая по умолчанию загружает первую страницу. Я также сделал галочку if (pageTokens.length != 0), чтобы кнопка «Предыдущая страница» не отображалась, если это первая страница.
Эй, поэтому я изменил функцию, так что теперь токены предыдущих страниц хранятся в массиве, при следующем вызове функции я назначаю последний элемент в массиве
previousPageToken, но теперь кнопка по какой-то причине только обновляет страницу (я редактировал вопрос с кодом)