节点js中的异步编程可通过猫鼬模型传递常量/预定义的强制值

时间:2018-08-14 07:58:05

标签: javascript node.js express asynchronous mongoose

我有多个问题,请仔细阅读代码。

1)如何通过模型传递常量/预定义的强制值?

例如我有一些字段,用户必须传递这些值和一些常量才能在kafkaSchema.config []和livySchema.args []内部传递。我要传递的代码在同一问题线程的第二个问题中。

 const mongoose = require('mongoose');


const livy_schema = mongoose.Schema({
    file: { type: String, required: true },
    name: { type: String, required: true },
    className: { type: String, required: true },
    args: [{ type: mongoose.Schema.Types.Mixed, required: true }] //here i have constants to pass on to 
});

const kafka_schema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    name: { type: String, required: true, unique: false },
    config: { type: mongoose.Schema.Types.Mixed, required: true } //here i have constants to pass on to 
});


const enrichedEventSchema = mongoose.Schema({
    _id: mongoose.Schema.Types.ObjectId,
    projectId: { type: mongoose.Schema.Types.ObjectId, ref: 'Project', required: true },
    name: { type: String, required: true, unique: true },
    description: { type: String, required: false },
    type: { type: String, enum: ["Enriched"], required: true },
    format: { type: String, enum: ["JSON", "DELIMITED", "FixedWidth", "LOG"], required: true },
    kafka: [kafka_schema],
    livy: [livy_schema]  // how to make this schema required:true?
});

module.exports = mongoose.model('EnrichedEvent', enrichedEventSchema);

2)如何使此代码异步运行,现在使其同步工作。例如,它能够将事件数据保存在数据库的事件集合中,然后更新项目集合,然后调用axios.post方法依次调用我的livy服务器和kafka服务器。我想做的是将事件数据保存在数据库的事件集合中,然后(同步)更新项目集合,同时我想同时(异步)调用我的livy和kafka服务器。

router.post("/:projectId/events/enriched", (req, res, next) => {
    const enrichedEvent = new EnrichedEvent({
        _id: mongoose.Types.ObjectId(),
        name: req.body.name,
        projectId: req.params.projectId, //taking from url
        description: req.body.description,
        type: req.body.type,
        format: req.body.format,
        kafka: req.body.kafka,
        livy: req.body.livy
    });
    enrichedEvent.save()
        .then(result => {
            console.log(result);
            res.status(201).json({
                message: "Event stored",
                createdEvent: {
                    _id: result._id,
                    projectId: result.projectId,
                    name: result.name,
                    description: result.description,
                    type: result.type,
                    kafka: result.kafka,
                    livy: result.livy
                }
            });

            Project.findOneAndUpdate({ _id: result.projectId },
                { $push: { enrichedEvents: result._id } })
            axios.post("http://52.xxx.xxx.199:8998/batches", result.livy)
                .then(function (response) {
                    console.log(response);
                })
                .then(axios.get("http://52.xxx.xxx.199:8998/batches/"), function (res) {
                    console.log(res);
                })
            axios.post("http://52.xxx.xxx.199:8083/connectors", result.kafka)
                .then(function (response) {
                    console.log(response);
                })
                .catch(err => {
                    console.log(err);
                    res.status(500).json({
                        error: err
                    });
                });
        });
});

问题似乎有点冗长,但是关于SO的有效问题。请指引我正确的方向。

2 个答案:

答案 0 :(得分:2)

1)

const enrichedEventSchema = mongoose.Schema({
    // ...
    livy: { type: [livy_schema], required: true }
});

2)

return enrichedEvent.save().
  then(result => {
    // ...
    return Project.findOneAndUpdate(/*...*/);
  }).
  then(() => {
    // ...
    return Promise.all([axios.post(/*...*/), axios.post(/*...*/]);
  });

答案 1 :(得分:1)

嘿,尝试以下操作:

1)用于保存用户输入的配置并具有默认常数。您可以使用猫鼬pre save钩子。

https://mongoosejs.com/docs/middleware.html#pre

livy_schema.pre('save', function(next) {
  this.args = { ...this.args, ...CONSTANTS }; //I'm use es6's spread operator
  next();
});

kafka_schema.pre('save', function(next) {
  this.config = { ...this.config, ...CONSTANTS }; //I'm use es6's spread operator
  next();
});

2)对于第二个问题:请尝试以下操作:

axios.all([
  axios.post("http://52.221.178.199:8998/batches", result.livy),
  axios.post("http://52.221.178.199:8083/connectors", result.kafka)
]);