无法摆脱全局变量(需要使其非全局)



我正在制作一个显示播放列表总持续时间的web应用程序。这里我们处理的是YouTube API。我想知道如何去掉全局变量newPageToken。此外,我还需要在这个代码片段的第三个函数中使用它。

let newPageToken = null;
// Next page for more results (Max 50 per page)
function getNextTokenURL() {
console.log(newPageToken);
return newPageToken
? `${playlistItemsURL}&playlistId=${extractedPlaylistIDId}&pageToken=${newPageToken}&key=${API_KEY}`
: `${playlistItemsURL}&playlistId=${extractedPlaylistIDId}&key=${API_KEY}`;
}

async function getVideoIdsForPageToken() {
try {
const { data } = await axios.get(getNextTokenURL());
const nextPageToken = data.nextPageToken;
const videoIds = data.items.map((video) => {
return video.contentDetails.videoId;
});
return { videoIds, nextPageToken };
} catch (e) {
if (e.response) {
const { code, message } = e.response.data.error;
throw new Error(`StatusCode ${code}. Reason: ${message}`);
console.log("Errow while fetching videos list.");
} else {
throw new Error(e.message);
}
}
}

// Navigates between the videos per page and adds them (Maximum 50)
async function getPlaylistData() {
try {
const { videoIds, nextPageToken } = await getVideoIdsForPageToken();
let pageToken = nextPageToken;
newPageToken = pageToken;
const returnedVideoIds = [];
returnedVideoIds.push(getDetailsForVideoIds(videoIds));
const videoGroups = await Promise.all(returnedVideoIds);

for (const group of videoGroups) {
for (const video of group) {
finalTotalDuration += returnedToSeconds(video.contentDetails.duration);
}
}
// console.log(videoIds);
if (nextPageToken) {
await getPlaylistData();
}
} catch (e) {
throw new Error(e.message);
console.log("Error while navigating between video pages.");
}
}```

假设

  1. finalTotalDuration也是在某处声明的全局变量(不是个好主意)
  2. 多个用户的多个播放列表调用getPlaylistData

解决方案您需要确保getPlaylistData是独立的,并返回finalTotalDuration作为返回值(而不是设置全局值)

要使它独立,它本质上必须是迭代的。它应该是一个递归函数,执行以下操作

async function getPlaylistTotalDuration(newPageToken) {
// Step 1: Create the required query URL based on the newPageToken parameter
// Step 2: Start a local duration counter
// Step 3: Get the video details based on the URL created in Step 1
// Step 4: Get the durations in seconds and add it to the local duration counter created in Step 2
// Step 5: Check if the return of Step 3 has a nextPageToken, if so do a recursive call to self with the new token
// Step 6: Return the final value, which will propogate back in a recursive function
}

你可以简单地像

那样调用这个函数
let finalTotalDuration = getPlaylistTotalDuration(null); // or getPlaylistTotalDuration();

例如下面的getPlaylistTotalDurationgetPlaylistData方法

的替代

async function getVideoIdsForPageToken(url) {
try {
const { data } = await axios.get(url);
const nextPageToken = data.nextPageToken;
const videoIds = data.items.map((video) => {
return video.contentDetails.videoId;
});
return { videoIds, nextPageToken };
} catch (e) {
if (e.response) {
const { code, message } = e.response.data.error;
throw new Error(`StatusCode ${code}. Reason: ${message}`);
console.log("Errow while fetching videos list.");
} else {
throw new Error(e.message);
}
}
}

async function getPlaylistTotalDuration(newPageToken) {
try {        
// Step 1: Create the required query URL based on the newPageToken parameter
let url = newPageToken
? `${playlistItemsURL}&playlistId=${extractedPlaylistIDId}&pageToken=${newPageToken}&key=${API_KEY}`
: `${playlistItemsURL}&playlistId=${extractedPlaylistIDId}&key=${API_KEY}`;
// Step 2: Start a local duration counter
let totalDuration = 0;
// Step 3: Get the video details based on the URL created in Step 1
const { videoIds, nextPageToken } = await getVideoIdsForPageToken(url);
const returnedVideoIds = [];
returnedVideoIds.push(getDetailsForVideoIds(videoIds));
const videoGroups = await Promise.all(returnedVideoIds);
for (const group of videoGroups) {
for (const video of group) {
// Step 4: Get the durations in seconds and add it to the local duration counter created in Step 2
totalDuration += returnedToSeconds(video.contentDetails.duration);
}
}
// Step 5: Check if the return of Step 3 has a nextPageToken, if so do a recursive call to self with the new token
if (nextPageToken) {
totalDuration += await getPlaylistTotalDuration(nextPageToken);
}
// Step 6: Return the final value, which will propogate back in a recursive function
return totalDuration;
} catch (e) {
throw new Error(e.message);
console.log("Error while navigating between video pages.");
}
}

注意:我并没有实际运行上面的代码,但希望你能知道需要做什么。

最新更新