如何在启动另一个之前等待自动迁移启动脚本完成?

时间:2016-02-25 02:07:44

标签: node.js loopbackjs

我使用启动脚本来创建一些模型和关系。例如,我可能会这样:

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

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

我知道loopback-boot执行filename alphabetical orderserver/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之前添加一小段等待,因为这看起来很脆弱,并且不能保证父模型的存在,特别是如果数据源恰好是缓慢的

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

是否有一种好方法可以在开始使用子模式之前等待父模型自动迁移完成?

2 个答案:

答案 0 :(得分:4)

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

示例:

module.exports = function (app, cb) {
  var db = app.dataSources.db;

  // update all database models
  db.autoupdate(function (err) {
    if (err) throw err;
    cb();
  });
};

答案 1 :(得分:0)

一种方法是keep looping,直到在数据源中找到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