javascript - 链接承诺以创建 ec2 实例
问题描述
我想以以前使用回调创建 ec2 实例的承诺方式重写脚本。我的逻辑是首先尝试描述安全组。如果不存在,则创建一个,否则继续描述密钥对。如果密钥对不存在,则创建一个并将私钥写入文件,否则继续创建实例。
不知何故,我设法做到了如下,但我对代码的平坦度不满意。仍然有很多缩进。此外,我发现我的逻辑迫使我将链式 Promise 嵌套在 catch 块中,这不是那些教程中人们通常这样做的方式,从而使我怀疑使用 Promise 的方式和最初目的。
var describeSecurityGroupsInstance = ec2.describeSecurityGroups(securityGroups).promise()
//1st level chain
describeSecurityGroupsInstance.then(function(data){
console.log("SecurityGroups Already Exist")
}).catch(function(err){
console.log("Unable to describe SecurityGroup", err)
var createSecurityGroupInstance = ec2.createSecurityGroup(securityGroup).promise()
//2nd level chain
createSecurityGroupInstance.then(function(data){
console.log("SecurityGroup test created")
var describeKeyPairsInstance = ec2.describeKeyPairs(keyPairs).promise()
return describeKeyPairsInstance
}).then(function(data){
console.log("KeyPair Already Exist, make sure you have private key locally to proceed")
}).catch(function(err){
console.log("Unable to describe KeyPairs", err)
var createKeyPairInstance = ec2.createKeyPair(keyPair).promise()
//3rd level chain
createKeyPairInstance.then(function(data){
console.log("KeyPair test created")
const writeFileInstance = util.promisify(fs.writeFile)
privateKey=data.KeyMaterial
return writeFileInstance('test.pem',privateKey)
}).then(function(data){
console.log("keypair content write to file")
var instancePromise = ec2.runInstances(instanceParams).promise()
return instancePromise
}).then(function(data){
console.log("instance just created")
console.log(data)
}).catch(function(err){
console.log("Unable to create KeyPair or unable to write to file or create instance", err, err.stack)
})
})
})
所以现在,我有 3 级承诺链。
我的第一个问题是我能否describeKeyPairsInstance
在 catch 块之后立即将承诺放入顶级链中describeSecurityGroupsInstance
,因为从逻辑上讲,在与 securityGroup 检查之后,我们应该检查 KeyPairs 或相反。(IMO 这两个步骤之间的顺序无关紧要,如果我错了)。基本上我可以忍受嵌套链来解决 securityGroups 的不存在,因为它是必须的,但不是describeKeyPairsInstance
一部分。如果这个目标可以实现,我认为writeFileInstance
也可以附加到顶级链上,那么问题就解决了。所以问题变成了如何将承诺从二级链返回到顶级链。现在虽然我认为这不可行,但如果有解决方案,我真的很感激。
我的第二个问题是创建 ec2 实例本身的逻辑。我应该简单地摆脱describeSecurityGroups/KeyPairs
这两个承诺,而不是根据createSecurityGroup/KeyPair
承诺的拒绝来检查存在吗?如果是这样,那么无论 securityGroup 和 keyPair 是否存在,我都可以链接 promise。但是幂等的说,我们不应该先检查存在吗?
我的第三个问题是关于 Promise 的一般用法。将承诺链嵌套在 catch 块中是不好的做法吗?如果是这样,有或没有承诺的替代方法是什么?
回答任何问题都会有所帮助。提前致谢。
解决方案
通过“反转”成功/失败逻辑,ec2.describeSecurityGroups
您 ec2.describeKeyPairs
可以“扁平化”此代码
const writeFileInstance = util.promisify(fs.writeFile);
const describeSecurityGroupsInstance () => ec2.describeSecurityGroups(securityGroups).promise()
.then(() => { throw 'SecurityGroups Already Exist'}, err => err);
const describeKeyPairsInstance = () => ec2.describeKeyPairs(keyPairs).promise()
.then(() => { throw 'KeyPair Already Exist, make sure you have private key locally to proceed'}, err => err);
describeSecurityGroupsInstance()
.then(res => {
console.log("Unable to describe SecurityGroup", res);
return ec2.createSecurityGroup(securityGroup).promise();
})
.then(describeKeyPairsInstance)
.then(res => {
console.log("Unable to describe KeyPairs", res);
return ec2.createKeyPair(keyPair).promise();
})
.then(data => {
console.log("KeyPair test created");
privateKey = data.KeyMaterial;
return writeFileInstance('test.pem',privateKey);
})
.then(data => {
console.log("keypair content write to file")
return ec2.runInstances(instanceParams).promise();
})
.then(data => {
console.log("instance just created");
console.log(data);
})
.catch(err => {
if (typeof err === 'string') {
console.log(err);
} else {
console.log(err, err.stack);
}
});
使用 async/await(以及反转逻辑),代码看起来更干净
const writeFileInstance = util.promisify(fs.writeFile);
const describeSecurityGroupsInstance () => ec2.describeSecurityGroups(securityGroups).promise()
.then(() => { throw 'SecurityGroups Already Exist'}, err => err);
const describeKeyPairsInstance = () => ec2.describeKeyPairs(keyPairs).promise()
.then(() => { throw 'KeyPair Already Exist, make sure you have private key locally to proceed'}, err => err);
try {
const sec = await describeSecurityGroupsInstance();
console.log("Unable to describe SecurityGroup", sec);
await ec2.createSecurityGroup(securityGroup).promise();
const kpi = await describeKeyPairsInstance();
console.log("Unable to describe KeyPairs", kpi);
const kp = await ec2.createKeyPair(keyPair).promise();
console.log("KeyPair test created");
privateKey = kp.KeyMaterial;
await writeFileInstance('test.pem',privateKey);
console.log("keypair content write to file");
const data = await ec2.runInstances(instanceParams).promise();
console.log("instance just created");
console.log(data);
} catch(err) {
if (typeof err === 'string') {
console.log(err);
} else {
console.log(err, err.stack);
}
});
推荐阅读
- virtualization - 嵌套虚拟化 KVM:进入失败,硬件错误 0x7
- networking - ns 在 /usr/bin/tclsh8.6 中找到了正确版本的 tclsh,但 ns2 似乎不再存在
- c# - Cake 的指令或程序集引用构建错误
- android - 无法检索 Firabase 存储图像 URL
- ms-access - 内部 OLE 自动化错误
- java - 我的 Spring Boot 中的事务有问题 - 我有一个异常,但事务正在提交
- spring - 用于获取指标的 Prometheus java/Spring API
- c++ - std atomic synchronisation and non atomic variable : not a stale data?
- android - 如何让应用在谷歌搜索中可搜索?
- r - 从字符串中删除括号