如何等待自动迁移启动脚本完成,然后再启动另一个脚本



我正在使用引导脚本来创建一些模型和关系。例如,我可能有这个:

+-------+                +----------+
| Order | --belongsTo--> | Customer |
+-------+                +----------+

我想创建:1 Customer 和 1 Order属于该Customer

我知道环回引导按文件名字母顺序执行server/boot中的脚本,所以我有以下引导脚本:

// 0-create-customer.js
module.exports = function(app) {
    app.dataSources.mongoDs.autoupdate('Customer', function(err) {
        if (err) throw err;
        var obj = {name: 'Bob'};
        app.models.Customer.findOrCreate({where: obj}, obj
        , function(err, customer) {
            if (err) throw err;
        });
    });
};

对于Order,我首先找到Customer并创建订单 customer.id

// 1-create-order.js
module.exports = function(app) {
    app.dataSources.mongoDs.autoupdate('Order', function(err) {
        if (err) throw err;
        app.models.Customer.findOne({where: {name: 'Bob'}}
        , function(err, customer) {
            if (err) throw err;
            var obj = {customerId: customer.id, amount: 42};
            app.models.Order.findOrCreate({where: obj}, obj
            , function(err, order) {
                if (err) throw err;
            });
        });
    });
};

问题是,引导脚本似乎不会等到创建模型后再退出,因此有时我在第二个脚本中会遇到这些错误:

TypeError: Cannot read property 'id' of null

参考这一行:

            var obj = {customerId: customer.id, amount: 42};
                                   ^

我宁愿在创建Order之前不添加一小段等待,因为这看起来很不稳定,并且不能保证父模型的存在,尤其是在数据源碰巧很慢的情况下。

我也不想将所有这些代码合并到一个文件中,因为我的真实项目有很多模型,这将导致一个巨大的无法维护的文件。

有没有好方法可以等待父模型自动迁移完成,然后再开始子模型?

您可以使用额外的回调参数创建异步引导脚本,并在脚本准备就绪时调用它。

例:

module.exports = function (app, cb) {
  var db = app.dataSources.db;
  // update all database models
  db.autoupdate(function (err) {
    if (err) throw err;
    cb();
  });
};

一种方法是继续循环,直到在数据源中找到Customer

因此,Order创建脚本可能如下所示:

// 1-create-order.js
module.exports = function(app) {
    app.dataSources.mongoDs.autoupdate('Order', function(err) {
        if (err) throw err;
        var customerId = null;
        function addOrder(customerName, obj) {
            if (customerId === null) {
                app.models.Customer.findOne(
                    {where: {name: customerName}}, function(err, customer) {
                    if (err) throw err;
                    if (customer !== null) {
                        customerId = customer.id;
                    }
                });
                setTimeout(addOrder, 1000, customerName, obj);
                return;
            }
            obj.customerId = customerId;
            app.models.Order.findOrCreate({where: obj}, obj
            , function(err, order) {
                if (err) throw err;
            });
        }
        addOrder('Bob', {amount: 42});
    });
}

因此,函数 addOrder 将继续使用 setTimeout 调用自身,直到创建Customer并在数据库中找到,它将用于创建Order

相关内容

最新更新