首页 > 解决方案 > 使用 Javascript 在 Google Drive 中创建树形目录结构

问题描述

我正在尝试使用 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),所以我想知道递归创建多个给定文件夹的正确方法是什么异步调用的性质。我是否需要放置一个始终被调用并选择下一步做什么的控制器功能?

谢谢 !

标签: javascriptgoogle-apigoogle-drive-apigoogle-api-js-client

解决方案


在这种情况下,我发现新的异步 javascript 语法更容易理解。

方法

您正在checkPhrFolder同步运行该函数,而其他两个依赖于异步 api 调用的函数正在等待 promise 解析以返回一个值。checkPhrFolder当您在同步执行中评估它时,这将导致 phr 未定义。

基本上为了这个工作,你应该链接你的承诺解决方案,以便正确使用它们的返回值。新的 javascript 语法虽然使您能够用更少的代码行编写异步函数。使用关键字asyncawait您可以控制 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语句中。

参考

异步/等待


推荐阅读