Node.js 如何等待自动迁移启动脚本完成后再启动另一个脚本?
我正在使用引导脚本创建一些模型和关系。例如,我可能有:Node.js 如何等待自动迁移启动脚本完成后再启动另一个脚本?,node.js,loopbackjs,Node.js,Loopbackjs,我正在使用引导脚本创建一些模型和关系。例如,我可能有: +-------+ +----------+ | Order | --belongsTo--> | Customer | +-------+ +----------+ 我想创建:1个客户,以及属于该客户的1个订单 我知道loopback boot在中执行server/boot中的脚本,因此我有以下引导脚本: // 0-create-customer.js module.ex
+-------+ +----------+
| Order | --belongsTo--> | Customer |
+-------+ +----------+
我想创建:1个客户
,以及属于该客户的1个订单
我知道loopback boot在中执行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;
});
});
};
对于订单
,我首先找到客户
,并使用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};
^
我不希望在创建订单之前添加一个小的等待时间,因为这看起来很脆弱,并且不能保证父模型的存在,尤其是在数据源速度较慢的情况下
我也不希望将所有这些代码合并到一个文件中,因为我真正的项目有很多模型,这将导致一个巨大的无法维护的文件
在启动子模型之前,是否有一种等待父模型自动迁移完成的好方法?您可以使用额外的回调参数创建异步启动脚本,并在脚本准备就绪时调用它
例如:
module.exports = function (app, cb) {
var db = app.dataSources.db;
// update all database models
db.autoupdate(function (err) {
if (err) throw err;
cb();
});
};
您可以使用额外的回调参数创建异步启动脚本,并在脚本准备就绪时调用它
例如:
module.exports = function (app, cb) {
var db = app.dataSources.db;
// update all database models
db.autoupdate(function (err) {
if (err) throw err;
cb();
});
};
一种方法是直到在数据源中找到客户为止
因此,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一种方法是直到在数据源中找到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
我在。在调用回调之前,它是否会阻止其他启动脚本的执行?是的,它就是这样做的。我在中看到了这一点,但我不理解回调的作用。在调用回调之前,它是否会阻止其他启动脚本的执行?是的,它就是这样做的。请不要使用这种方法。如果您的引导脚本是异步的,则它必须具有异步(app,cb)
签名,并且它还将使您的代码和生活更轻松。请不要使用这种方法。如果你的引导脚本是异步的,它必须有异步的(app,cb)
签名,这也会让你的代码和生活变得更简单。