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

我创建了一个 API,它调用 get cloudWatch AWS API 并返回可以在我的应用程序上绘制的数据点。我对每个包都有单独的路由(如下面的路由代码所示)。此 API 使用 REST MVC 方法。

所以我正在用我的功能做几件事。

  1. 从 SQLite3 数据库中读取 EC2 实例数据以获取有关正在运行的实例(IP、instance_id、instance_launchtime)的信息,以便我可以将其放入 AWS 开发工具包中 getMetricStatistics API 所需的参数中。

  2. 然后将来自 step1 的数据放入参数数组中(3 个以 3 个不同的度量数据点响应)。这会循环遍历每个参数,将其插入到 getMetricStatistics API(一个接一个,因为 getMetricStatistics 不会一次接受多个指标)以获取该实例的数据点并将它们推送到数组中。

因为我相信数据库是异步的,这就是为什么我对它附加了一个承诺。当我将端点加载到浏览器中时,它只会继续加载并且不会显示任何数据。但是,当我刷新页面时,它会正确显示所有结果...

API的模型:


// Call AWS Cost Explorer API

const 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 Service

var 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 function

const 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);

};


RISEBY
浏览 110回答 1
1回答

叮当猫咪

就目前而言,在第二个 Promise 构造函数中,insightParams 保证尚未组合,因为insightParams = [.....]它位于异步调用的回调中。因此,程序流程需要确保所有的“promise2”内容仅在“promise1”完成后才发生。如果异步函数在尽可能低的级别被“承诺”,那么高级代码中的事情就会变得简单得多。所以在模型中做两件事:承诺cloudWatch.getMetricStatistics()编写 packageById() 以返回Promise而不是接受回调。模型因此变为:const AWS = require('aws-sdk'); // no changeconst config = require('./AWSconfig'); // no changeconst database = require('./db'); // no changeconst insightdb = database.insightdb; // no changeAWS.config.update({    accessKeyId: config.accessKeyId,    secretAccessKey: config.secretAccessKey,    region: config.region}); // no changevar 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()
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript