【发布时间】:2022-01-06 05:15:53
【问题描述】:
我正在尝试制作一种使用驱动器 API 在谷歌驱动器中复制文件夹树的方法。我遇到了一些异步方法不起作用的问题,如果有人能发现代码中的缺陷,或者向我指出一些有用的文章,那将非常有帮助。
我需要等待导致错误的行,因为下一次递归调用需要使用“复制”功能所需的文件夹的 ID。它返回一个承诺,所以它看起来应该可以工作。
一般来说,我对异步编程不是很有经验,所以我可能会忽略一些简单的事情,但我已经坚持了一段时间了。谢谢!!
代码:
function authorize() {
const auth = new google.auth.GoogleAuth({
keyFile: 'creds.json',
scopes: SCOPES
})
return google.drive({version: 'v3', auth})
}
function search(driveService, parentFolder) {
return new Promise((resolve, reject) => {
driveService.files.list({
pageSize: 20,
q: `'${parentFolder}' in parents and trashed = false`,
fields: 'files(id, name, mimeType)'
}).then(({data}) => resolve(data))
.catch(err => reject(err))
})
}
function createRoot(driveService, CLIENT_NAME, NEW_FOLDER_LOCATION) {
let fileMetadata = {
'name': CLIENT_NAME,
'mimeType': 'application/vnd.google-apps.folder',
'parents': [NEW_FOLDER_LOCATION]
}
return new Promise((resolve, reject) => {
const file = driveService.files.create({
resource: fileMetadata,
fields: 'id'
}, function(err, file) {
if(err) {
reject(err);
} else {
resolve(file.data.id);
}
})
})
}
function copy(driveService, copyContentId, contentNewName, root){
let fileMetadata = {
'name': contentNewName,
'parents': [root]
};
return new Promise((resolve, reject) => {
const file = driveService.files.copy({
'fileId': copyContentId,
'resource': fileMetadata
}, function(err, file) {
if(err) {
reject(err);
} else {
resolve(file.data.id);
}
})
})
}
async function recursive(driveService, startSearch, rootFolder) {
let children = await search(driveService, startSearch);
if(children.files.length > 0) {
children.files.forEach((element) => {
if(element.mimeType === 'application/vnd.google-apps.folder') {
let name = element.name.replace('Last, First', CLIENT_NAME);
let folderID = await copy(driveService, element.id, name, rootFolder);
recursive(driveService, element.id, folderID);
} else {
let name = element.name.replace('Last, First', CLIENT_NAME);
let fileID = await copy(driveService, element.id, name, rootFolder);
}
})
} else {
console.log('end of branch');
}
}
async function run() {
try{
const google = await authorize();
const root = await createRoot(google, CLIENT_NAME, NEW_FOLDER_LOCATION);
await recursive(google, START_SEARCH, root);
} catch(err) {
console.log('error', err);
}
}
run();
输出:
app.js:75
let folderID = await copy(driveService, element.id, name, rootFolder);
^^^^^
SyntaxError: await is only valid in async functions and the top level bodies of modules
at Object.compileFunction (node:vm:352:18)
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
at Module._compile (node:internal/modules/cjs/loader:1065:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
at node:internal/main/run_main_module:17:47
【问题讨论】:
-
我想知道你为什么要为递归而烦恼。做一个 file.list 并使用 nextpage 令牌下载所有内容。然后在本地进行排序。如果你要递归遍历文件夹,你会很快吃掉你的配额。
-
@DaImTo 很好,但我不确定如何实现相同的结构,我要复制的文件夹可能会有多个级别的子文件夹。
标签: node.js google-drive-api asynchronous-javascript