【问题标题】:Node.js Async Module RequireNode.js 异步模块需要
【发布时间】:2018-12-01 03:03:24
【问题描述】:

我有一个关于基于 express 的 node.js 应用程序的问题,该应用程序依赖于第一个 require()。这是我的第一个 node.js 应用程序。第一个 require() 命中 AWS ec2 参数存储以收集数据库的凭证。在此要求以异步方式解决之前,我无法连接到数据库。

我发现最好的方法是导出一个回调并将其余的 require() 语句包装在第一个 require() 的回调中。 这是一种不好的做法吗?

//app.js

var appConfig = require('./config/appconfig');

appConfig.fetchAppConfig(function(err, result) {
    if(err) {
        console.log(err);
        console.error("Server failed to startup. Config parameters not available.");
    }
    else {
        var express = require('express');
        var path = require('path');
        var cookieParser = require('cookie-parser');
        ...
        app.use(bodyParser.json());
        etc
        ...

//appConfig.js

module.exports = function fetchAppConfig(callback) {
    getCredentials(function(err, result) {
        if(err) {
            console.log(err);
            callback(err);
        } else {
            awsLogin.paramStoreService(result).then(
                data => {
                    appConfig = decodeAppConfig(data.Parameter.Value);
                    callback(null, appConfig);
                }
            ).catch(
                error => {
                    console.error(error);
                    callback(err);
                }
            )
        }
    })
}

我错过了一个更简单的选择吗?

如果我有这个逻辑来将配置拉到部署代码的某个地方,我会更好吗?

【问题讨论】:

    标签: node.js express require


    【解决方案1】:

    我将定义几个函数,一个用于请求凭据,另一个用于在检索到凭据后连接到数据库。您可以使用async 模块的series 函数,它可以让您轻松控制应用程序的流程。

    来自文档:

    依次运行tasks集合中的函数,每一个运行 一旦上一个功能完成。如果有任何功能 系列将错误传递给它的回调,不再运行函数,并且 立即使用错误的值调用回调。否则, 任务完成后,回调会收到一组结果。

    这是一个例子:

    var async = require('async');
    
    function getCredentials(callback) {
        callback(null, {
            user: 'hello',
            pass: 'world',
        });
    };
    
    function connectToDatabase(callback, creds) {
        console.log('Connecting to database => ' + JSON.stringify(creds));
    
        callback(null, 'Done');
    };
    
    async.series([
        getCredentials,
        connectToDatabase,
    ],
    function(err, results) {
        console.error(err);
        console.log(results);
    });
    

    【讨论】:

      【解决方案2】:

      直到节点支持顶级等待,下面是我用于这个确切用例的解决方案。

      // index.js

      (async () => {
        await require('./config').initialize();
        require('./app');
      })();
      

      // config.js

      const _ = require('lodash');
      
      const secretKeys = ['secret1', 'secret2']; 
      
      const parameterHierarchyPrefix = `/${process.env.NODE_ENV}/app/`;
      const getParamNameWithoutHierarchy = name => _.replace(name, new RegExp(`${parameterHierarchyPrefix}(.*)`), '$1');
      
      const config = {};
      config.initialize = async (callback = () => {}) => {
        try {
          // initialize aws sdk and ssm
          const AWS = require('aws-sdk');
          AWS.config.update({
            region: 'us-west-2',
            accessKeyId: S3_ACCESS_KEY,
            secretAccessKey: S3_SECRET,
          });
          const ssm = new AWS.SSM();
      
          // map secret keys to lowercase
          const secretNames = _.map(secretKeys, key => `${parameterHierarchyPrefix}key`);
      
          // this api only allows fetching 10 params per call
          const secretFetchBatches = _.chunk(secretNames, 10);
      
          // fetch secrets from aws parameter store
          let secrets = {};
          for (let i = 0; i < _.size(secretFetchBatches); i += 1) {
            const parameters = await ssm.getParameters({
              Names: secretFetchBatches[i],
              WithDecryption: true,
            }).promise();
            secrets = {
              ...secrets,
              ..._.zipObject(_.map(parameters.Parameters, ({ Name }) => ([getParamNameWithoutHierarchy(Name)])), _.map(parameters.Parameters, 'Value')),
            };
          }
      
          // write the secrets into the config object
          _.each(secrets, (v, k) => constants[k] = v);
      
          // invoke the callback
          callback();
        } catch (e) {
          throw e
        }
      };
      
      module.exports = config;
      

      【讨论】:

        猜你喜欢
        • 2013-11-09
        • 2012-12-04
        • 1970-01-01
        • 1970-01-01
        • 2018-09-24
        • 2016-12-23
        • 2017-10-24
        • 1970-01-01
        • 2018-04-24
        相关资源
        最近更新 更多