我是JavaScript和Async / Await概念的新手。
我正在使用驱动器API example,并且能够打印出驱动器中的文件。但是,当我尝试将响应存储到名为files
的变量中时,控制台将打印未定义的内容。
我认为console.log(files)
在响应生成之前正在打印?
有什么想法可以使listFiles()
函数一直等到files变量充满响应后才能将数据发送到前端吗?
'use strict'
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
// Load client secrets from a local file.
class FileUploadController {
index ({ request, response, view }) {
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Drive API.
authorize(JSON.parse(content), listFiles);
});
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getAccessToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
function getAccessToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error retrieving access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
let files;
/**
* Lists the names and IDs of up to 10 files.
* @param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
async function listFiles(auth) {
const drive = google.drive({version: 'v3', auth});
// await drive.files.list({
// pageSize: 10,
// fields: 'nextPageToken, files(id, name)',
// }, (err, res) => {
// if (err) return console.log('The API returned an error: ' + err);
// files = res.data.files;
// console.log(files)
// if (files.length) {
// console.log('Files:');
// files.map((file) => {
// console.log(`${file.name} (${file.id})`);
// });
// } else {
// console.log('No files found.');
// }
// });
drive.files.list({
pageSize: 10,
fields: 'nextPageToken, files(id, name)',
}).then( res => {
files = res.data.files
console.log(files);
})
}
console.log(files);
return view.render('file-upload', {files: 'files are here'})
}
}
module.exports = FileUploadController
运行此控制器时,我的终端显示以下内容
info: serving app on http://127.0.0.1:3333
undefined
[ { id: '1Pg5KODwcdlG7oV64pOSl9tBMtzy_p498', name: 'photo.jpg' },
{ id: '1_u248zVI2swg0KLMaL9oRERkGUNHbV2u', name: 'photo.jpg' },
{ id: '1duLnJrPYkd75ZNFZx0OvTUPYYmZAaNzS', name: 'photo.jpg' },
{ id: '1TJC6-VfuusA6rXgtC9E3WQQsFg4JZJkn',
name: 'etosEntityDiagram.drawio' },
{ id: '1XUg_Xju4hZr2KTEsEt8WHz0bAz8isAEo',
name: 'Untitled Diagram.drawio' },
{ id: '14MsZFOZGLZqEZyNbI0yYTo4I4aW0gK7K',
name: 'ProjectFileManager.drawio' },
{ id: '0B3g4WnyGCaYQdExQSm9ZYmkwRTQ',
name: 'High Elves - 8th Edition.pdf' },
{ id: '1ok4WdMaalXWd9y0PGENewMlElPUxEqTNY3p8wwch_h4',
name: 'Google VM Pricing' },
{ id: '1GhRSL8y9jzm8eefwFFvCp2AuJhtGUOEx', name: 'gcp.drawio' },
{ id: '1OC_D8CNe7CXzzkJpMNYKkVT1KteS2vQulov2E-D5KNs',
name: 'Bucket Pricing Example' } ]
答案 0 :(得分:1)
对不起,我不太了解您到底想做什么,使用async/await
还是只是了解如何以任何方式将files
转换为render
方法。我在async/await
上重新编码了一下代码,因为您未提供服务器,所以无法检查它。希望它能使您对如何使用async/await
的理解更加清楚:
'use strict'
const fs = require('fs');
const util = require('util');
const readline = require('readline');
const { google } = require('googleapis');
const fsp = fs.promises;
readline.Interface.prototype.question[util.promisify.custom] = function(prompt) {
return new Promise(resolve =>
readline.Interface.prototype.question.call(this, prompt, resolve),
);
};
readline.Interface.prototype.questionAsync = util.promisify(readline.Interface.prototype.question);
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
class FileUploadController {
async index({ request, response, view }) {
try {
const files = await this.getFiles();
return view.render('file-upload', { files });
} catch (error) {
// ... you must handle the error
}
}
async getFiles() {
try {
// Load client secrets from a local file.
const content = await fsp.readFile('credentials.json');
const oAuth2Client = await this.authorize(JSON.parse(content));
const files = await this.listFiles(oAuth2Client);
return files;
} catch (error) {
console.error('Error loading client secret file:', error);
throw error;
}
}
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
*/
async authorize(credentials) {
const { client_secret, client_id, redirect_uris } = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
try {
const token = await fsp.readFile(TOKEN_PATH);
oAuth2Client.setCredentials(JSON.parse(token));
return oAuth2Client;
} catch (error) {
console.error(error);
return this.getAccessToken(oAuth2Client);
}
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
async getAccessToken(oAuth2Client) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const code = await rl.questionAsync('Enter the code from that page here: ');
rl.close();
try {
const token = await oAuth2Client.getToken(code);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
await fsp.writeFile(TOKEN_PATH, JSON.stringify(token));
return oAuth2Client
} catch (error) {
console.error('Error retrieving access token', error);
throw error;
}
}
/**
* Lists the names and IDs of up to 10 files.
* @param {google.auth.OAuth2} auth An authorized OAuth2 client.
*/
async listFiles(auth) {
try {
const drive = google.drive({ version: 'v3', auth });
const response = await drive.files.list({
pageSize: 10,
fields: 'nextPageToken, files(id, name)',
});
return response.data.files;
} catch (error) {
console.error('The API returned an error:', error);
throw error;
}
}
}
module.exports = FileUploadController;
我并不是说这段代码写得很好,但它确切显示了如何使用async/await
以及如何获取files
变量以将其传递给渲染。 / p>