如何使用 .map 正确制作 promise.all 函数?

How to properly make a promise.all function with a .map?

我试图询问这个 here 的简化版本,但我意识到它可能没有包含足够的信息。所以不幸的是,我只是要 post 整件事,希望它不会冒犯任何人。

基本上我有 4 个函数,它们的用途如下:

1.InitializeDrive() 获取用户电子邮件并使用 Google 的 JWT 用户模拟方法 return 该用户的适当授权。

2.listfiles() 调用 InitializeDrive() 进行授权并检索与相关用户授权相关的文档列表。

3.singleUserData() 需要一个文件列表,例如来自 listfiles() 的文件列表并对其进行优化。

4.all_user_data() 旨在成为结合所有上述功能的 Promise.all 异步功能,并映射到用户数组 getListUsers(),创建 主数组 包含每个用户的所有精炼文件数据。

基本上我的问题是'how can make the all_user_data() in such a way that it will return the aforementioned master array?'。我对异步编程比较陌生,并且一直存在与嵌套函数混淆的问题。

// loads credentials from .env file
require('dotenv').config();
const util = require('util');
const { google } = require('googleapis');
const { logger } = require('handlebars');
const { getListUsers } = require('./get_users');
const target_users = getListUsers();

function initializeDrive(version, user) {
return new Promise((resolve, reject) => {
const client_email = process.env.GOOGLE_CLIENT_EMAIL;
console.log(client_email);
// add some necessary escaping so to avoid errors when parsing the private key.
const private_key = process.env.GOOGLE_PRIVATE_KEY.replace(/\n/g, '\n');
// impersonate an account with rights to create team drives
const emailToImpersonate = user;
const jwtClient = new google.auth.JWT(
  client_email,
  null,
  private_key,
  ['https://www.googleapis.com/auth/drive'],
  emailToImpersonate,
);
return google.drive({
  version: version,
  auth: jwtClient,
 });
 });
}

const listfiles = async (pagetokenObj, user) => {
let pageToken = '';
let version = 'v3';
if (pagetokenObj !== undefined) {
pageToken = pagetokenObj.pageToken;
}
const drive = await initializeDrive(version, user);
//const drive = initializeDrive(version,user);
return new Promise((resolve, reject) => {
drive.files.list(
  {
    pageSize: 100,
    fields:
      'nextPageToken, files(id, name, owners(emailAddress), 
  sharingUser(emailAddress), permissions)',
    ...(pageToken ? { pageToken } : {}),
  },
  function (err, { data: { nextPageToken = '', files = [] } = {} }) {
    if (err) {
      return reject(err);
    }
    if (!nextPageToken) {
      return resolve(files);
    }
    // if page token is present we'll recursively call ourselves until
    // we have a complete file list.
    return listfiles({ pageToken: nextPageToken }).then((otherfiles) => {
      resolve(files.concat(otherfiles));
    });
    },
   );
 });
};

//Function returns formatted
const singleUserData = async (files) => {
return new Promise((resolve, reject) => {
const single_user_json = await listfiles();
const res = single_user_json
  .filter((doc) => Boolean(doc.permissions))
  .map((doc) => {
    return {
      id: doc.id,
      sharedWith: doc.permissions
        .filter((permission) => permission.type === 'user')
        .map((permission) => {
          return {
            emailAddress: permission.emailAddress,
            role: permission.role || null,
          };
        }), // convert the perm object into a string (email address)
    };
  });
// this is how you get nicer console.logs instead of just [Object] and [Array] BS
// 
console.log(util.inspect(res, { showHidden: false, depth: null, colors: true }));
if (err) {
    return reject(err);
  }
  if (!nextPageToken) {
    return resolve(files);
};
})
};

const all_user_data = async() => {
const users = await getListUsers();
const pagetokenObj = "{ pageToken = '' } = {}";
Promise.all(
users.map(async (pagetokenObj,user) => {
  const files = await listfiles(pagetokenObj, user);
  console.log(files);

  const singleUserData = await singleUserData(files)
  console.log(singleUserData);
  }),
 );
 console.log(users)
 }


//returnJSON();
//getListUsers();
//singleUserData();
all_user_data();

你快到了。

  1. 删除 all_user_data
  2. 中的列表文件调用
  3. 将用户传递给 singleUserData
  4. 删除 all_user_data
  5. 中的 pagetokenObj
  6. 直接在 users.map 和 return promise 中删除 async 和 await
  7. 等待Promise.all,将其分配给一个变量并return那个变量
  8. 删除 singleUserData 中不必要的 Promise 包装
  9. 更改 singleUserData 的函数签名以接收用户
  10. 将用户传递给 singleUserData 中的列表文件
  11. Return res 而不是 singleUserData
  12. 中的文件

以下是我对 all_user_data 和 singleUserData 所做的更改:

// Function returns formatted
async function singleUserData(user) {
  const single_user_json = await listfiles(user);
  const res = single_user_json
    .filter((doc) => Boolean(doc.permissions))
    .map((doc) => {
      return {
        id: doc.id,
        sharedWith: doc.permissions
          .filter((permission) => permission.type === "user")
          .map((permission) => {
            return {
              emailAddress: permission.emailAddress,
              role: permission.role || null,
            };
          }), // convert the perm object into a string (email address)
      };
    });

  return res;
};

async function getAllUserData() {
  const users = await getListUsers();
  const usersData = await Promise.all(
    users.map((user) => {
      return singleUserData(user);
    })
  );

  return usersData;
};

const usersData = await getAllUserData();

我终于明白了。基本上需要等待更多并正确声明异步。

// loads credentials from .env file
require('dotenv').config();
const util = require('util');
const { google } = require('googleapis');
const { logger } = require('handlebars');
const { getListUsers } = require('./get_users');
const target_users = getListUsers();

async function initializeDrive(user) {
 // return new Promise((resolve, reject) => {
    const client_email = process.env.GOOGLE_CLIENT_EMAIL;
    console.log(user + ': ' + client_email);
    // add some necessary escaping so to avoid errors when parsing the private key.
    const private_key = process.env.GOOGLE_PRIVATE_KEY.replace(/\n/g, '\n');
    // impersonate an account with rights to create team drives
    const emailToImpersonate = await user;

    const jwtClient = new google.auth.JWT(
      client_email,
      null,
      private_key,
      ['https://www.googleapis.com/auth/drive'],
      emailToImpersonate,
    );
    return google.drive({
      version: "v3",
      auth: jwtClient,
    });
  //});
}
//
async function listfiles(pagetokenObj, user) {
    let pageToken = '';
   if (pagetokenObj !== undefined) {
      pageToken = pagetokenObj.pageToken;
   }
  const drive = await initializeDrive(user); 
  //console.log(drive)
  return new Promise((resolve, reject) => {
    drive.files.list(
      {
        pageSize: 100,
        fields:
          'nextPageToken, files(parents, id, name, properties, owners(emailAddress), sharingUser(emailAddress), permissions)',
        ...(pageToken ? { pageToken } : {}),
      },
      function (err, { data: { nextPageToken = '', files = [] } = {} }) {
        if (err) {
          return reject(err);
        }
        if (!nextPageToken) {
          return resolve(files);
        }
        // if page token is present we'll recursively call ourselves until
        // we have a complete file list.
        return listfiles({ pageToken: nextPageToken }).then((otherfiles) => {
          resolve(files.concat(otherfiles));
        });
      },
    );
  });
};

async function singleUserData(user) {
    const pagetokenObj = "{ pageToken = '' } = {}"
    const single_user_json = await listfiles(pagetokenObj, user);
 //   return new Promise ((resolve, reject) => {
  
  console.log(user+ ":" + JSON.stringify(single_user_json));
  const res = await single_user_json
    .filter((doc) => Boolean(doc.permissions))
    .map((doc) => {
      return {
        id: doc.id,
        sharedWith: doc.permissions
          .filter((permission) => permission.type === 'user')
          .map((permission) => {
            return {
              emailAddress: permission.emailAddress,
              role: permission.role || null,
            };
           
          }) // convert the perm object into a string (email address)
          
      };
    });

  return JSON.stringify(res);
//})
}

async function getAllUserData() {
  try {
    const users = await getListUsers();
   // const userString = JSON.parse(users);
    console.log("test22222222222222: " + users)
    const usersData = await Promise.all(
    users.map((user) => {
      return singleUserData(user);
      
    })
     );
    console.log("[" + usersData + "]");
    return usersData;
  } catch (error) {
    console.log(error);
  }
}

getAllUserData();