在重复执行的递归函数中捕获挡路

2022-03-24 00:00:00 递归 async-await aws-sdk javascript
我有一个递归函数,用于从AWS上的CodeCommit存储库获取SQL文件并按顺序运行它们。在运行下一个文件之前,我们需要等待前一个文件完成。如果其中一个sql文件失败,我需要Catch挡路返回有关失败的文件的信息。

我现在看到的代码是,对于repo中的每个sql文件,捕捉挡路重复一次。根据我的理解,"抛出"语句应该返回到最初调用该函数的函数的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

您的代码对于如何用推荐答案编写实用而健壮的异步程序有许多明显的误解。关于下面的代码,我仍然有一些需要修改的地方,但是我不能建议,因为没有提供关于codecommit.getFilerunScripts的信息。如果您对此答案有任何疑问,我很乐意为您提供帮助-

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回调还可以返回正确排序程序的承诺。请参见下面的示例-

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

相关文章