Node.js Google Sheets API中appendData函数传参的技术疑问
appendData时不用传参,以及如何修改为带额外参数的回调函数 作为JavaScript新手,你遇到的这个问题其实是回调函数机制的典型应用场景,我来一步步给你拆解清楚:
1. 为什么不用给appendData传参?
你看这段代码:
fs.readFile('client_secret.json', function processClientSecrets(err, content) { authorize(JSON.parse(content), appendData); });
这里你传递给authorize的是appendData这个函数本身的引用,而不是立刻执行它(如果是执行的话会写成appendData())。
再看你的authorize函数逻辑:
function authorize(credentials, callback) { // ... 授权流程代码 ... fs.readFile(TOKEN_PATH, function (err, token) { if (err) { getNewToken(oauth2Client, callback); } else { oauth2Client.credentials = JSON.parse(token); callback(oauth2Client); // 重点在这里! } }); }
当授权流程完成、拿到oauth2Client(也就是你说的auth参数)之后,authorize会主动调用你传进来的callback函数,并且把oauth2Client作为参数传给它——这个callback就是你之前传的appendData。所以appendData的auth参数是authorize在合适的时机帮你传的,你根本不用自己手动传。
2. 为什么加括号会报错?
如果你写成authorize(JSON.parse(content), appendData()),这时候你是立刻执行了appendData函数,并把它的返回值传给authorize。但appendData需要auth参数,你没传的话第一步就会报错;就算不报错,appendData的返回值大概率不是一个函数,等authorize后续想调用callback的时候,就会出现“不是函数”的错误。
3. 如何修改为appendData(auth, values)?
如果你想让appendData接收额外的values参数,需要用闭包或者箭头函数把values“包”进去,同时保留auth参数的传递路径,这里给你两种常用方法:
方法一:用闭包创建回调函数
// 先定义一个能包裹values的函数 function createAppendCallback(values) { // 返回一个能接收auth参数的函数,这个函数可以访问外部的values return function(auth) { var sheets = google.sheets('v4'); sheets.spreadsheets.values.append({ auth: auth, range: '你的表格范围', // 替换成你的实际范围,比如'Sheet1!A:C' valueInputOption: 'USER_ENTERED', resource: { values: values } }, function(err, response) { if (err) { console.log('API调用错误: ' + err); return; } console.log('数据追加成功,新增行数: ' + response.data.updates.updatedRows); }); }; } // 调用时的写法 const myValues = [['张三', '25', '北京'], ['李四', '30', '上海']]; fs.readFile('client_secret.json', function processClientSecrets(err, content) { authorize(JSON.parse(content), createAppendCallback(myValues)); });
方法二:用箭头函数简化写法
如果觉得上面的函数有点繁琐,箭头函数可以更简洁地实现闭包:
// 先写好带两个参数的appendData function appendData(auth, values) { var sheets = google.sheets('v4'); sheets.spreadsheets.values.append({ auth: auth, range: '你的表格范围', valueInputOption: 'USER_ENTERED', resource: { values: values } }, function(err, response) { if (err) { console.log('API调用错误: ' + err); return; } console.log('数据追加成功'); }); } // 调用时用箭头函数中转参数 const myValues = [['张三', '25', '北京']]; fs.readFile('client_secret.json', function processClientSecrets(err, content) { authorize(JSON.parse(content), (auth) => appendData(auth, myValues)); });
这里的箭头函数(auth) => appendData(auth, myValues)会在authorize调用它时,把auth参数接收下来,再连同myValues一起传给appendData,完美实现你的需求。
内容的提问来源于stack exchange,提问作者Paul Ahuevo

