【发布时间】:2016-12-24 13:22:31
【问题描述】:
我正在尝试使用他们的 Mongoose 模型将文档插入 MongoDB,并且我想使用 Promise。由于此数据来源于 MSSQL 数据库,因此每个集合中的文档与其他集合中的文档具有外键关系。
示例代码如下:
const Promise = require('bluebird');
const mongoose = require('mongoose');
const Make = Promise.promisifyAll(require('../models/make-model'));
const Nameplate = Promise.promisifyAll(require('../models/nameplate-model'));
const Vehicle = Promise.promisifyAll(require('../models/vehicle-model'));
const { makes, nameplates, vehicles } = require('./sqlExport.json');
const logErr = (err) => console.error(err);
Promise.resolve(
mongoose.connection.db.dropDatabase()
)
.then(() => (
Promise.all(
makes.map(make => (
Make.create(make).then(makeRes => console.log(`Created make ${makeRes}`))
))
)),
logErr
)
.then(() => (
Promise.all(
nameplates.map(nameplate => {
const { sqlMakeId, sqlModelId, sqlSubModelId } = nameplate;
return Make.find({ sqlMakeId })
.then(makeRes => {
if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`);
const finalNameplate = Object.assign({}, nameplate, { mongoMakeId: makeRes[0]._id });
return Nameplate.create(finalNameplate);
})
.then(nameplateRes => {
console.log(`Created nameplate ${nameplateRes}`);
});
})
)),
logErr
)
.then(() => (
Promise.all(
vehicles.map(vehicle => {
const { sqlVehicleId, sqlMakeId, sqlSubModelId } = vehicle;
const extraParams = {};
return Make.find({ sqlMakeId })
.then(makeRes => {
if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for make.sqlMakeId: ${sqlMakeId}`);
extraParams.mongoMakeId = makeRes[0]._id;
return Nameplate.find({ sqlSubModelId });
})
.then(nameplateRes => {
if (makeRes.length !== 1) throw new Error(`duplicate or non-existent key for nameplate.sqlSubModelId: ${sqlSubModelId}`);
extraParams.mongoNameplateId = nameplateRes[0]._id;
const finalVehicle = Object.assign({}, vehicle, extraParams);
return Vehicle.create(finalVehicle);
})
.then(vehicleRes => {
console.log(`Created vehicle ${vehicleRes}`);
});
})
)),
logErr
)
.catch(logErr);
问题是,有时车辆插入在任何铭牌插入之前全部运行,因此无法找到 mongoNameplateId 的正确文档_id。
完整代码在这里:https://gist.github.com/jeremyjs/1d5509350d3cae69d0e83f1d6478eeb2
【问题讨论】:
-
看起来应该对我有用。如果您可以将代码剥离到准系统以使调试更容易,那将有所帮助。我喜欢做的一件事是用 setTimeout 调用替换所有异步调用,这些调用在大约一秒钟后解决一个承诺,并打印一条关于它们正在替换的消息,即
console.log("Make.find('blah')") -
Nameplate和VehicleAPI 已被承诺,但没有证据表明已调用承诺的方法。Nameplate.create()应该是Nameplate.createAsync(),Vehicle.create()应该是Vehicle.createAsync()吗? -
@Roamer-1888 好电话。我从未使用过蓝鸟,但查看它声明的文档
Note that the original methods on the object are not overwritten but new methods are created with the Async-suffix. For example, if you promisifyAll the node.js fs object use fs.statAsync to call the promisified stat method.
标签: node.js mongodb promise foreign-keys