递归函数中重复执行的catch块
Catch Block in Recursive Function Executing Repeatedly
我有一个递归函数,用于从 AWS 上的 CodeCommit 存储库获取 SQL 文件并按顺序 运行 它们。在 运行 下一个文件之前,我们需要等待上一个文件完成。如果 SQL 文件之一失败,我需要 catch 块来 return 关于失败文件的信息。
我目前在代码中看到的是,catch 块对存储库中的每个 SQL 文件重复一次。根据我的理解,'throw' 语句应该 return 到最初调用该函数的函数的 catch 块。谁能指出我在这里做错了什么?
const getFileData = async (newSQLFiles,processed=[]) => {
try{
if(newSQLFiles.length ===0){
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
return processed;
}
var params = {
filePath: newSQLFiles[0].relativePath,
repositoryName: 'testDBScripts' //Use environment variable
};
const data = await codecommit.getFile(params).promise();
await runScripts(data);
processed.push(newSQLFiles[0].relativePath)
}catch(err){
console.log(err)
throw [err,processed];
}
return await getFileData(newSQLFiles.slice(1),processed);
}
await getFileData(newSQLFiles)
.then(processed=>console.log("Following products are updated.",processed))
.catch(async ([e, file])=> {
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
//await codePipelineJobFailed("SQL file " + file + " failed with : " + e)
throw new Error("SQL file " + file + " failed with : " + e)}
)
在JavaScript中,当函数遇到return
语句时,它将停止函数形式的进一步执行。
可能它目前不起作用,因为在函数内的 catch
之后,您正在返回。
所以,为了解决您的问题,我想这样做:
const getFileData = async (newSQLFiles,processed=[]) => {
try{
if(newSQLFiles.length ===0){
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
return processed;
}
var params = {
filePath: newSQLFiles[0].relativePath,
repositoryName: 'testDBScripts' //Use environment variable
};
const data = await codecommit.getFile(params).promise();
await runScripts(data);
processed.push(newSQLFiles[0].relativePath)
}catch(err){
console.log(err)
throw [err,processed];
}
await getFileData(newSQLFiles.slice(1),processed);
}
await getFileData(newSQLFiles)
.then(processed=>console.log("Following products are updated.",processed))
.catch(async ([e, file])=> {
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
//await codePipelineJobFailed("SQL file " + file + " failed with : " + e)
throw new Error("SQL file " + file + " failed with : " + e)}
)
请注意,我已经从 try catch
块之后的函数范围中删除了 return
。
您的代码包含许多关于如何在 JavaScript 中编写实用且健壮的异步程序的明显误解。关于下面的代码,我还有一些地方要更改,但我无法提供建议,因为未提供有关 codecommit.getFile
和 runScripts
的信息。如果您对此答案有任何疑问,我很乐意提供帮助 -
async function getFileData(files) {
const result = []
for (const f of files) {
try {
const data = await codecommit.getFile({
filePath: f.relativePath,
repositoryName: 'testDBScripts'
}).promise()
await runScripts(data)
result.push(f.relativePath)
}
catch (e) {
throw new Error("SQL file " + f + " failed with : " + e.message)
}
}
return result
}
使用起来是这样的-
getFileData(newSQLFiles)
.then(console.log, console.error)
.finally(_ => client.release())
.finally(_ => pool.end())
或者如果你更喜欢 catch
,这也是一样的 -
getFileData(newSQLFiles)
.then(console.log)
.catch(console.error)
.finally(_ => client.release())
.finally(_ => pool.end())
注意 .finally
回调也可以 return 一个正确排序程序的承诺。请参阅下面的示例 -
const delay = (ms,x) =>
new Promise(r => setTimeout(_ => console.log(x) || r(x), ms))
delay(1000,"a")
.then(_ => delay(1000,"b"))
.then(_ => delay(200, "result"))
.finally(_ => delay(500,"client released"))
.finally(_ => delay(1000,"pool closed"))
.then(console.log, console.error)
a
b
result
client released
pool closed
result
如果序列中的任何承诺被拒绝或抛出错误,.finally
处理程序仍会被调用 -
const delay = (ms,x) =>
new Promise(r => setTimeout(_ => console.log(x) || r(x), ms))
delay(1000,"a")
.then(_ => Promise.reject(Error("SQL FAILURE")))
.then(_ => delay(200, "result"))
.finally(_ => delay(500,"client released"))
.finally(_ => delay(1000,"pool closed"))
.then(console.log, console.error)
a
client released
pool closed
Error: SQL FAILURE
我有一个递归函数,用于从 AWS 上的 CodeCommit 存储库获取 SQL 文件并按顺序 运行 它们。在 运行 下一个文件之前,我们需要等待上一个文件完成。如果 SQL 文件之一失败,我需要 catch 块来 return 关于失败文件的信息。
我目前在代码中看到的是,catch 块对存储库中的每个 SQL 文件重复一次。根据我的理解,'throw' 语句应该 return 到最初调用该函数的函数的 catch 块。谁能指出我在这里做错了什么?
const getFileData = async (newSQLFiles,processed=[]) => {
try{
if(newSQLFiles.length ===0){
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
return processed;
}
var params = {
filePath: newSQLFiles[0].relativePath,
repositoryName: 'testDBScripts' //Use environment variable
};
const data = await codecommit.getFile(params).promise();
await runScripts(data);
processed.push(newSQLFiles[0].relativePath)
}catch(err){
console.log(err)
throw [err,processed];
}
return await getFileData(newSQLFiles.slice(1),processed);
}
await getFileData(newSQLFiles)
.then(processed=>console.log("Following products are updated.",processed))
.catch(async ([e, file])=> {
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
//await codePipelineJobFailed("SQL file " + file + " failed with : " + e)
throw new Error("SQL file " + file + " failed with : " + e)}
)
在JavaScript中,当函数遇到return
语句时,它将停止函数形式的进一步执行。
可能它目前不起作用,因为在函数内的 catch
之后,您正在返回。
所以,为了解决您的问题,我想这样做:
const getFileData = async (newSQLFiles,processed=[]) => {
try{
if(newSQLFiles.length ===0){
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
return processed;
}
var params = {
filePath: newSQLFiles[0].relativePath,
repositoryName: 'testDBScripts' //Use environment variable
};
const data = await codecommit.getFile(params).promise();
await runScripts(data);
processed.push(newSQLFiles[0].relativePath)
}catch(err){
console.log(err)
throw [err,processed];
}
await getFileData(newSQLFiles.slice(1),processed);
}
await getFileData(newSQLFiles)
.then(processed=>console.log("Following products are updated.",processed))
.catch(async ([e, file])=> {
client.release();
await pool.end().then(() => console.log('DB Connection pool closed.'))
//await codePipelineJobFailed("SQL file " + file + " failed with : " + e)
throw new Error("SQL file " + file + " failed with : " + e)}
)
请注意,我已经从 try catch
块之后的函数范围中删除了 return
。
您的代码包含许多关于如何在 JavaScript 中编写实用且健壮的异步程序的明显误解。关于下面的代码,我还有一些地方要更改,但我无法提供建议,因为未提供有关 codecommit.getFile
和 runScripts
的信息。如果您对此答案有任何疑问,我很乐意提供帮助 -
async function getFileData(files) {
const result = []
for (const f of files) {
try {
const data = await codecommit.getFile({
filePath: f.relativePath,
repositoryName: 'testDBScripts'
}).promise()
await runScripts(data)
result.push(f.relativePath)
}
catch (e) {
throw new Error("SQL file " + f + " failed with : " + e.message)
}
}
return result
}
使用起来是这样的-
getFileData(newSQLFiles)
.then(console.log, console.error)
.finally(_ => client.release())
.finally(_ => pool.end())
或者如果你更喜欢 catch
,这也是一样的 -
getFileData(newSQLFiles)
.then(console.log)
.catch(console.error)
.finally(_ => client.release())
.finally(_ => pool.end())
注意 .finally
回调也可以 return 一个正确排序程序的承诺。请参阅下面的示例 -
const delay = (ms,x) =>
new Promise(r => setTimeout(_ => console.log(x) || r(x), ms))
delay(1000,"a")
.then(_ => delay(1000,"b"))
.then(_ => delay(200, "result"))
.finally(_ => delay(500,"client released"))
.finally(_ => delay(1000,"pool closed"))
.then(console.log, console.error)
a
b
result
client released
pool closed
result
如果序列中的任何承诺被拒绝或抛出错误,.finally
处理程序仍会被调用 -
const delay = (ms,x) =>
new Promise(r => setTimeout(_ => console.log(x) || r(x), ms))
delay(1000,"a")
.then(_ => Promise.reject(Error("SQL FAILURE")))
.then(_ => delay(200, "result"))
.finally(_ => delay(500,"client released"))
.finally(_ => delay(1000,"pool closed"))
.then(console.log, console.error)
a
client released
pool closed
Error: SQL FAILURE