为了账号安全,请及时绑定邮箱和手机立即绑定

返回承诺不适用于 AWS 开发工具包

返回承诺不适用于 AWS 开发工具包

RISEBY 2022-05-26 17:46:36
我创建了一个 API,它调用 get cloudWatch AWS API 并返回可以在我的应用程序上绘制的数据点。我对每个包都有单独的路由(如下面的路由代码所示)。此 API 使用 REST MVC 方法。所以我正在用我的功能做几件事。从 SQLite3 数据库中读取 EC2 实例数据以获取有关正在运行的实例(IP、instance_id、instance_launchtime)的信息,以便我可以将其放入 AWS 开发工具包中 getMetricStatistics API 所需的参数中。然后将来自 step1 的数据放入参数数组中(3 个以 3 个不同的度量数据点响应)。这会循环遍历每个参数,将其插入到 getMetricStatistics API(一个接一个,因为 getMetricStatistics 不会一次接受多个指标)以获取该实例的数据点并将它们推送到数组中。因为我相信数据库是异步的,这就是为什么我对它附加了一个承诺。当我将端点加载到浏览器中时,它只会继续加载并且不会显示任何数据。但是,当我刷新页面时,它会正确显示所有结果...API的模型:// Call AWS Cost Explorer APIconst AWS = require('aws-sdk');const config = require('./AWSconfig');const database = require('./db');const insightdb = database.insightdb;AWS.config.update({  accessKeyId: config.accessKeyId,  secretAccessKey: config.secretAccessKey,  region: config.region,});//Linking AWS CloudWatch Servicevar cloudWatch = new AWS.CloudWatch();const packageById = (packageId, callback) => {  insightdb.all(    'SELECT * FROM ec2Instance WHERE package_id == ?',    packageId,    (err, rows) => {      if (err) {        callback(err, null);      } else {        callback(null, rows);      }    }  );};// Parameter class to feed into the CloudWatch getMetricStatistics functionconst CWParams = function(reqDate, metricName,service,launchTime,instanceId) {  (this.EndTime = reqDate) /* required */,    (this.MetricName = metricName) /* required */,    (this.Namespace = service) /* required */,    (this.Period = 3600) /* required */,    (this.StartTime = launchTime) /* ${createDate}`, required */,    (this.Dimensions = [      {        Name: 'InstanceId' /* required */,        Value: instanceId /* required */,      },    ]),    (this.Statistics = ['Maximum']);};//Exports variables to the controller (so they can be re-used)module.exports = { cloudWatch, CWParams, packageById };API 的路径:module.exports = app => {  const insight = require('../controllers/insight.controller.js');  app.get('/insights/aws/:packageKey', insight.getAnalytics);};
查看完整描述

1 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

就目前而言,在第二个 Promise 构造函数中,insightParams 保证尚未组合,因为insightParams = [.....]它位于异步调用的回调中。因此,程序流程需要确保所有的“promise2”内容仅在“promise1”完成后才发生。

如果异步函数在尽可能低的级别被“承诺”,那么高级代码中的事情就会变得简单得多。所以在模型中做两件事:

  • 承诺cloudWatch.getMetricStatistics()

  • 编写 packageById() 以返回Promise而不是接受回调。

模型因此变为:

const AWS = require('aws-sdk'); // no change

const config = require('./AWSconfig'); // no change

const database = require('./db'); // no change


const insightdb = database.insightdb; // no change


AWS.config.update({

    accessKeyId: config.accessKeyId,

    secretAccessKey: config.secretAccessKey,

    region: config.region

}); // no change


var cloudWatch = new AWS.CloudWatch(); // no change


// Promisify cloudWatch.getMetricStatistics() as  cloudWatch.getMetricStatisticsAsync().

cloudWatch.getMetricStatisticsAsync = (metric) => {

    return new Promise((resolve, reject) => {

        cloudWatch.getMetricStatistics(metric, function(err, data) {

            if (err) {

                if(!err.message) { // Probably not necessary but here goes ...

                    err.message = 'Error occured while running cloudWatch getMetricStatistcs API: ';

                }

                reject(err); // (very necessary)

            } else {

                resolve(data);

            }

        });

    });

};


// Ensure that packageById() returns Promise rather than accepting a callback.

const packageById = (packageId) => {

    return new Promise((resolve, reject) => {

        insightdb.all('SELECT * FROM ec2Instance WHERE package_id == ?', packageId, (err, rows) => {

            if (err) {

                reject(err);

            } else {

                resolve(rows);

            }

        });

    });

};

现在getAnalytics()可以这样写:


exports.getAnalytics = (req, res) => {

    packageById(req.params.packageKey)

    .then(data => {

        const currentDate = new Date().toISOString();

        let insightParams = [

            new CWParams(currentDate, 'CPUUtilization', 'AWS/EC2', data[0].launch_time, data[0].instance_id),

            new CWParams(currentDate, 'CPUCreditBalance', 'AWS/EC2', data[0].launch_time, data[0].instance_id),

            new CWParams(currentDate, 'CPUCreditUsage', 'AWS/EC2', data[0].launch_time, data[0].instance_id)

        ];

        // Composition of `insightParams` is synchronous so you can continue 

        // with the `cloudWatch.getMetricStatisticsAsync()` stuff inside the same .then().

        return Promise.all(insightParams.map(metric => cloudWatch.getMetricStatisticsAsync(metric))); // Simple because of the Promisification above.

    }, err => {

        // This callback handles error from packageById() only,

        // and is probably unnecessary but here goes ...

        if(!err.message) {

            err.message = 'Error while getting the insight configuration data.';

        }

        throw err;

    })

    .then(metricResults => {

        res.send(metricResults);

        console.log('AWS CW API successful');

    })

    .catch(err => {

        // Any async error arising above will drop through to here.

        res.status(500).send({

            'message': err.message

        }));

    });

};

请注意,多个 catchres.status(500).send()不是必须的。沿着 Promise 链向下传播的错误允许单个终端.catch()


查看完整回答
反对 回复 2022-05-26
  • 1 回答
  • 0 关注
  • 109 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信