Javascript 链接承诺创建ec2实例

Javascript 链接承诺创建ec2实例,javascript,node.js,amazon-web-services,amazon-ec2,promise,Javascript,Node.js,Amazon Web Services,Amazon Ec2,Promise,我想以一种承诺的方式重写一个脚本,它以前使用回调创建ec2实例。我的逻辑是首先尝试描述安全组。如果不存在,则创建一个,否则继续描述密钥对。如果密钥对不存在,则创建一个密钥对并将privatekey写入文件,否则继续创建实例 不知何故,我设法做到了以下几点,但我对代码的平淡不满意。还有很多凹痕。此外,我发现我的逻辑迫使我在catch块中嵌套chain-promise,这与人们在那些教程中通常的做法不同,因此我怀疑使用promise的方式和最初目的 var describeSecurityGroup

我想以一种承诺的方式重写一个脚本,它以前使用回调创建ec2实例。我的逻辑是首先尝试描述安全组。如果不存在,则创建一个,否则继续描述密钥对。如果密钥对不存在,则创建一个密钥对并将privatekey写入文件,否则继续创建实例

不知何故,我设法做到了以下几点,但我对代码的平淡不满意。还有很多凹痕。此外,我发现我的逻辑迫使我在catch块中嵌套chain-promise,这与人们在那些教程中通常的做法不同,因此我怀疑使用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)
        })
    })
})
所以现在,我有三级承诺链

我的第一个问题是,我是否能够在捕获
describeSecurityGroupsInstance
的块之后,将
DescribeKeyPairInstance
放入顶级链中,因为在逻辑上,在与securityGroup进行检查后,我们应该检查密钥对,或者相反。(我认为这两个步骤之间的顺序无关紧要,如果我错了,请纠正我). 基本上,我可以忍受嵌套链来解决securitygroup不存在的问题,因为这是必须的,但不能忍受
descripbekeypairsinstance
部分。若这个目标能够实现,我认为
writeFileInstance
也可以附加到顶级链中,那个么问题就解决了。因此,问题就变成了如何将承诺从二级链返回到顶级链。现在,虽然我认为这是不可行的,但我真的很感激如果有一个解决办法

我的第二个问题是创建ec2实例本身的逻辑。我是否应该简单地去掉
descripesecuritygroup/KeyPairs
这两个承诺,而是基于
createSecurityGroup/KeyPairs
promise的拒绝来检查是否存在?如果是这样的话,那么我就可以保证不管securityGroup和keyPair是否存在。但从幂等意义上讲,我们不应该先检查存在性吗

我的第三个问题是关于允诺的一般用法。将承诺链嵌套在捕获块中是不好的做法吗?如果是,有无承诺的替代方式是什么

回答任何问题都会有帮助。提前感谢。

如果您不熟悉JavaScript ES7,请介绍它,它可以解决您描述的确切问题。它本质上是围绕你已经拥有的东西的语法糖分,但是它看起来确实更好,而不是做
。然后
并将它们链接在一起。

如果你不熟悉JavaScript ES7,它就是为了解决你正在描述的问题而引入的。它本质上是围绕你已经拥有的东西的语法糖分,但是它看起来确实更好,而不是做
。然后
并将它们链接在一起。

通过“反转”ec2的成功/失败逻辑。descripesecuritygroup
ec2。descripbeKeypairs
你可以“展平”这段代码

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);
    }
});
通过“反转”ec2.DescribeSecurityGroup和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);
    }
});

事实上,您将
函数(无论什么)
缩进到.then和.error中的新行中,这是因为代码缩进的程度超出了它的需要-除此之外,我无法立即看到其他编写代码的方法(除了将部分代码重构为函数,或者可能使用异步/等待)@JaromandaX去掉不必要的压痕确实会使它看起来更好。但主要问题仍然存在什么主要问题?如果代码可以正常工作,那么就没有什么大问题了intended@OscarZhang,编写的代码可能存在问题-将由“无法描述密钥对”处理程序捕获
ec2.createSecurityGroup()的失败。也许是故意的,也许不是。不管是哪种方式,捕获或捕获/重新显示该错误都是一个好主意,以证明您已经造成了该错误。事实上,您将
函数(无论什么)
缩进到.then and.error中的新行中。错误是将代码缩进的程度超出了它的需要-除此之外,我无法立即看到编写该代码的其他方式,(除了将一些代码重构为函数,或者可能使用async/await)@JaromandaX去掉不必要的缩进确实会使它看起来更好。但主要问题仍然存在。什么主要问题?如果代码按intended@OscarZhang,编写的代码可能存在问题-将通过“无法描述密钥对”捕获
ec2.createSecurityGroup()的故障处理程序。可能是有意的,也可能不是。无论哪种方式,捕获或捕获/重新显示该错误以证明是您造成的都是一个好主意。您知道这是一个更好的答案吗?如果您展示async/await对问题中的代码有多大帮助,因为我认为它不会像您想象的那样有多大帮助知道什么能让这成为一个更好的答案吗?如果你展示了async/await对问题中的代码有多大的帮助,因为我认为它不会像你想象的那么有帮助