我正在尝试使用Google Drive Javascript API构建简单的目录树。我想我应该检查该文件夹是否存在并创建它,然后最终添加其子级。所以我在下面建立了这些功能:
function createFolder(name, parent) {
if (!parent) parent = 'root';
var fileMetadata = {
'name': name,
'mimeType': 'application/vnd.google-apps.folder',
'parent': parent
};
gapi.client.drive.files.create({
'resource': fileMetadata,
'fields': 'id'
}).then(function (res) {console.log(res); return res.result['id'];}, function (err) {console.log(err); return null;});
}
function getFolder(name, parent) {
if (!parent) parent = 'root';
gapi.client.drive.files.list({
'pageSize': 1,
'fields': "nextPageToken, files(id, name, mimeType, parents)",
'q': "mimeType='application/vnd.google-apps.folder' \
and '" + parent + "' in parents \
and name = '" + name + "'"
}).then(
function (res) {console.log(res); var ret = res.result.files.length > 0 ? res.result.files[0]['id'] : null; return ret;},
function (err) {console.log(err);return null;}
);
}
function checkPhrFolder() {
var phr = getFolder('Personal Health Record');
console.log('get folder: '+phr);
if (!phr) {
console.log('creating ...');
phr = createFolder('Personal Health Record');
}
}
这只是检查我的第一个目录是否存在,如果不存在,则创建它。问题在于调用是异步的(使用“ then promises”),因此函数不会返回任何内容(例如,getFolder永远不会返回文件夹的id),所以我想知道递归创建多个文件夹的正确方法是什么异步调用的性质。我是否需要放置一个始终被调用的控制器功能并选择下一步?
谢谢!
在这种情况下,我发现新的异步javascript语法更容易理解。
您正在同步运行函数checkPhrFolder
,而依赖异步api调用的其他两个函数正在等待promise解析以便返回值。在同步checkPhrFolder
执行中评估phr时,这将导致phr未定义。
基本来说,您应该将您的promise解析链接起来,以便正确使用其返回值。尽管新的javascript语法使您可以用更少的代码行编写异步函数。使用关键字async
和await
,您可以控制Promise解析流程,并在进行正确的分配之前基本上等待异步函数返回。
async function createFolder(name, parent) {
if (!parent) parent = 'root';
var fileMetadata = {
'name': name,
'mimeType': 'application/vnd.google-apps.folder',
'parent': parent
};
const res = await gapi.client.drive.files.create({
'resource': fileMetadata,
'fields': 'id'
});
return res.result['id'];
}
async function getFolder(name, parent) {
if (!parent) parent = 'root';
const res = await gapi.client.drive.files.list({
'pageSize': 1,
'fields': "nextPageToken, files(id, name, mimeType, parents)",
'q': "mimeType='application/vnd.google-apps.folder' \
and '" + parent + "' in parents \
and name = '" + name + "'"
});
return res.result.files.length > 0 ? res.result.files[0]['id'] : null;
}
async function checkPhrFolder() {
var phr = await getFolder('Personal Health Record');
console.log('get folder: '+phr);
if (!phr) {
console.log('creating ...');
phr = createFolder('Personal Health Record');
}
}
通过这种方式,您的checPhrFolder
函数将几乎像以前一样容易阅读。当您在同步上下文中使用checkPhrFolder
函数时,将能够在同一then/catch
语句中包装其返回值。