JavaScript async/await and do/while loop
JavaScript async/await and do/while loop
当外部循环迭代次数少于大约100次时,以下脚本将按预期运行。如果外部循环迭代几千次,我可以看到我的console.log被混淆了。例如:
- 3x外环输出
- 1x内环输出
- 1x外环输出//不应发生,因为所有外环输出在内部循环输出之前
或
- 3x外环输出
- 2x内环输出//不应该发生,因为只有一个内环循环输出
还有很多其他奇怪的组合,但我认为这总是相同的原因。
在我的情况下,async/await和do/while循环的组合似乎并不顺利。我曾试图通过制作单独的递归函数来消除do/while循环,但都是徒劳的。还有别的办法吗?非常感谢您的帮助。
async function asyncGenerator() {
// other code
do {
// other code
var fileList = await listFiles(nextPageToken);
// other code
do {
// other code
var parents = await requestParents(fileList.result.items[0].parents[0].id);
// other code
} while (response.result.parents[0].isRoot === false);
// other code
} while (fileList.result.nextPageToken !== "undefined")
// other code
}
function listFiles(token) {
return gapi.client.drive.files.list({
'maxResults': sizeResults,
'pageToken': token,
'q': query
});
}
function requestParents(fileId) {
return gapi.client.drive.files.get({
'fileId': fileId
});
}
编辑:
- 根据要求,请在下面找到原始代码
- 我认为你需要创建一个新的谷歌开发者控制台项目并插入相应的"clientId"answers"apiKey"
- 在此期间,我用递归替换了外部do/while循环函数调用,但输出仍然很奇怪
- 我不知道如何包含browser.js和runtime.js,因此,脚本标记仍然包含我的路径
- 此外,我不确定这是否在片段中起作用:type="text/babel"src="js/driverlights.js"在第4个script标记中
"use strict";
var driveRights = (function() {
var clientId = 'YOUR CLIENT ID';
var apiKey = 'YOUR API KEY';
var scopes = 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.readonly https://www.googleapis.com/auth/drive.appfolder https://www.googleapis.com/auth/drive.apps.readonly https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.install https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/drive.photos.readonly https://www.googleapis.com/auth/drive.scripts';
function handleClientLoad() {
var initButton = document.getElementById('init');
initButton.onclick = function() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth(false, handleAuthResult), 1);
}
}
function checkAuth(imm, callback) {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: imm
}, callback);
}
function handleAuthResult(authResult) {
if (authResult) {
gapi.client.load('drive', 'v2', initialize);
} else {
$('#progress').html('Anmeldung fehlgeschlagen');
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
var timeOut = 120;
var counter = 0;
var tokenMemory;
var start = new Date().getTime();
var currentTime;
// Test data
var sizeResults = 1;
var parentFolders = ['0B11RmPttIhB3aFhaMzFQQ0Rjbm8', '0B6R9YDOGf_BUSC0wNW1lRWlnSmc', '0B6R9YDOGf_BUUHRoUW9tRkljUFk', '0B6R9YDOGf_BUfjc3QlZ1YU9Tb2lHcmhLVGhWc3FqSzE4S1dvZlhlLWd6aVFhUWdENWkyYkU'];
var newUser = 'TEST@TEST.COM';
var query = 'trashed = false';
var initialize = function() {
$('#start').click(function() {
asyncGenerator();
});
};
async function asyncGenerator(token) {
try {
// REQUEST FILES
counter += sizeResults;
tokenMemory = token;
await sleep(timeOut);
var fileList = await listFiles(token);
console.log("Requested so far: ", counter);
console.log("Number of received files: ", fileList.result.items.length);
console.log(fileList);
// END REACHED
if (fileList.result.items.length === 0) {
console.log("DONE - no more files");
return;
}
// CHECK FILES
var firstCheckResult = firstCheck(fileList.result.items[0]);
// Rights
if (firstCheckResult === "rights") {
$('#progress').append(`Rechte | ${fileList.result.items[0].title} | ${fileList.result.items[0].owners[0].displayName} | ${fileList.result.items[0].alternateLink} <br>`);
console.log("TO DO: rights");
}
// Check parents
if (firstCheckResult === "checkParents") {
var parentID = fileList.result.items[0].parents[0].id;
do {
console.log("Do while loop parents are not root");
await sleep(timeOut);
var response = await requestParents(parentID);
parentID = response.result.parents[0].id;
} while (response.result.parents[0].isRoot === false);
var secondCheckResult = secondCheck(response);
}
// No change
if (firstCheckResult === "notChange" || secondCheckResult === "notChange") {
console.log("TO DO: not");
}
// Change
if (firstCheckResult === "change" || secondCheckResult === "change") {
console.log("TO DO: change");
await sleep(timeOut);
await requestPermissions(fileList.result.items[0].id);
}
// REFRESH TOKEN IF NECESSARY
currentTime = new Date().getTime();
if (currentTime > (start + 2700000)) {
start = new Date().getTime();
console.log("Restart asyncGenerator! Reason: Create new token");
checkAuth(true, asyncGenerator);
}
// CHECK IF NEXT PAGE TOKEN EXISTS
if (typeof fileList.result.nextPageToken !== "undefined") {
asyncGenerator(fileList.result.nextPageToken);
} else {
console.log("DONE - no next page token");
}
// RESTART IF ERROR OCCURS
} catch (err) {
console.log(err);
if (err.result.error.code === 500) {
console.log("Restart asyncGenerator! Reason: Error 500");
asyncGenerator(tokenMemory);
}
if (err.result.error.message.indexOf("Es ist ein interner Fehler aufgetreten, der die Freigabe") > -1) {
console.log("Restart asyncGenerator! Reason: Permission Error");
asyncGenerator(tokenMemory);
}
}
}
function listFiles(token) {
return gapi.client.drive.files.list({
'maxResults': sizeResults,
'pageToken': token,
'q': query
});
}
function requestParents(fileId) {
return gapi.client.drive.files.get({
'fileId': fileId
});
}
function requestPermissions(fileId) {
return gapi.client.drive.permissions.insert({
'fileId': fileId,
'sendNotificationEmails': false,
'resource': {
'value': newUser,
'type': 'user',
'role': 'writer',
'name': 'Team'
}
});
}
function firstCheck(file) {
// File can't be shared -> output to site
if (file.writersCanShare === false) {
return "rights";
}
// File is forbidden folder -> do not change
else if (parentFolders.indexOf(file.id) > -1) {
return "notChange";
}
// File is root-folder and has no parents -> do change
else if (file.parents.length === 0 && parentFolders.indexOf(file.id) === -1) {
return "change";
}
// Parent-folder of file is root-folder and parent-folder ist not a forbidden folder -> do change
else if (file.parents[0].isRoot === true && parentFolders.indexOf(file.parents[0].id) === -1) {
return "change";
}
// Parent-folder of file is a forbidden-folder -> do not change
else if (parentFolders.indexOf(file.parents[0].id) > -1) {
return "notChange";
}
// If none of these exceptions is met -> check parent
else {
return "checkParents";
}
}
function secondCheck(file) {
// If file's parent is one of the forbidden folders-> do not change
if (parentFolders.indexOf(file.result.id) > -1) {
return "notChange";
} else {
return "change";
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
return {
start: handleClientLoad,
};
})();
driveRights.start();
.cover {
margin: 5% 0;
background: none;
}
.full {
background: url(cover.jpg) no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.coverbox {
background-color: rgba(255,255,255,0.8) !important;
}
.separator {
border: 0;
height: 1px;
background-image: -webkit-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
background-image: -moz-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
background-image: -ms-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
background-image: -o-linear-gradient(left, rgba(0,0,0,0), rgba(0,0,0,0.75), rgba(0,0,0,0));
}
#init, #start {
width: 200px;
margin-top: 10px;
}
<!DOCTYPE>
<html>
<head>
<title>Drive Rights</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/browser.js"></script>
<script type="text/babel" src="js/driverights.js"></script>
<script type="text/javascript" src="js/runtime.js"></script>
<script src="https://apis.google.com/js/client.js"></script>
</head>
<body class="cover full">
<div class="container">
<div class="jumbotron coverbox clearfix">
<h1>Drive Rights</h1>
<p>
Change file permissions for specific user.
</p>
<hr class="separator">
<div id="info" class="clearfix">
<p>
First click login, then start.
</p>
<p class="text-center">
<button type="button" class="btn btn-primary btn-lg" id="init">
Login
</button></br>
<button type="button" class="btn btn-primary btn-lg" id="start">
Start
</button>
</p>
</div>
<div id="progress"></div>
</div>
</body>
</html>
我在asyncGenerator
函数中没有看到嵌套的do while循环,但我确实看到asyncGenerator
可以递归调用(有时是间接调用),在每次调用过程中都会发生一些新的异步await
。不能保证这些await
表达式中的任何一个都将以相同的顺序完成,因此也不能保证console.log
语句总是按它们在代码中发生的顺序完成。你的一些await
表达式依赖于网络(例如await listFiles(...)
),而网络并不总是那么可预测。首先开始的请求可能不会首先完成,因此递归函数调用不会总是按预期执行。
要解决这个问题,可以做的一件事是重构递归调用,使其也使用await
,因此递归调用可能看起来像:
await asyncGenerator(fileList.result.nextPageToken);
相关文章:
- JavaScript while-loop不起作用
- While-Loop Logic JavaScript
- jquery while loop
- 为什么获胜'我的While Loop工作
- JavaScript - while loop
- JavaScript -- while loop
- Do While Loop for AJAX?
- 当IF满足要求时,停止Do While LOOP
- 如何打印While Loop
- JavaScript async/await and do/while loop
- Javascript in While Loop PHP
- Javascript while loop innerHTML
- While loop and setInterval()
- Javascript while loop = new to javascript
- 对while loop / indexOf()感到困惑
- Selenium While Loop?
- While LOOP - PHP -动态关闭括号
- Promise in while loop javascript
- 用While Loop &构建一个以年递增月份的函数;Momentjs
- JQuery while-loop在使用inArray比较优化数组内容时变得无响应