为什么这个Node片段没有被捕获拒绝Promise?

rum*_*ums 3 node.js promise async-await ecmascript-6 bluebird

我试图理解为什么我遇到的Promise拒绝异常不是由我在以下代码中的初始try/catch处理的(完整代码在此分支中)

在此特定错误中,nodeCf.deploy正在index.js中调用.

发生错误是因为我应该使用this.deployName,而不是stack.deployName 在我的console.log语句中.

我不明白的是为什么这被认为是一种不妥协的承诺拒绝.我不应该在初始调用nodeCf.deploy时遇到try/catch吗?

// index.js:

  switch (args.action) {
    case 'deploy':
      try {
        await nodeCf.deploy(stacks, envVars);
      } catch (e) {
        console.log(`deployment failed: `, e);
        process.exit(1);
      }
      break;
  < ... >

// nodeCf module:
async deploy(stacks, envVars) {
  var stackOutputs = {};
  await Promise.each(stacks, async(stack) => {
    stackOutputs[stack.name] = await stack.deploy(envVars, 
      stackOutputs).outputs;
  });
}

// stack.deploy:
async deploy(envVars, stackOutputs) {
this.load(envVars, stackOutputs);
await ensureBucket(this.infraBucket);
const s3Resp = await this.uploadTemplate()
const stackResp = await ensureAwsCfStack({
  StackName: this.deployName,
  Parameters: this.parameters,
  Tags: this.tags,
  TemplateURL: s3Resp.Location,
  Capabilities: [ 'CAPABILITY_IAM', 
    'CAPABILITY_NAMED_IAM' ]
});
this.outputs = _.map(stackResp.Outputs, (it) => 
  _(it).pick(['OutputKey', 'OutputValue'])
    .toPairs()
    .unzip()
    .tail()
    .fromPairs()
    .value());
console.log(`deployed ${stack.deployName}`); // 'stack' is causing exception
return this;
}
Run Code Online (Sandbox Code Playgroud)

Ber*_*rgi 8

这是你的问题:

stackOutputs[stack.name] = await stack.deploy(envVars, stackOutputs).outputs;
Run Code Online (Sandbox Code Playgroud)

请注意,这stack.deploy是一个async function?这意味着它返回一个promise - 而不是具有该outputs属性的实例.您正在访问.outputs承诺,这undefined将被await编辑得很好,但承诺及其拒绝被忽略.

你需要写

stackOutputs[stack.name] = (await stack.deploy(envVars, stackOutputs)).outputs;
//                         ^                                         ^
Run Code Online (Sandbox Code Playgroud)

或者为实例使用辅助变量.