Nodejs Sequelize 递归 async/await
Nodejs Sequelize recursive async/await
我正在努力处理递归循环和嵌套的 create/select 语句。我从具有以下结构的 post 请求接收到一个对象:
11.6042
---11.6042_01
---11.6042_02
---11.6042_02
---14x10-100
------14x10-100_01
---14x10-100
------14x10-100_01
---14x10-100
------14x10-100_01
---M10-DIN929_14020
---M10-DIN929_14020
---11.6042_05
需要的行为:递归遍历结构,将记录添加到部件 table,自连接父部件,连接部件库 table,如果不存在匹配创建部件库记录并匹配创建的记录.处理下一部分。
问题:14x10-100部分在结构中出现了3次。我想在 part_lib table 中为第 14x10-100 部分创建一条记录,并引用该记录三次。实际发生的情况是,对于每个 14x10-100 部分,都会创建 part_lib table 中的相应记录,而不是一次创建和两次匹配。如果我再次 运行 它会像预期的那样匹配。我怀疑我迷失在 promise/async 等待部分代码中。
相关代码下方。为了便于阅读,我删除了一些属性映射。我的想法是:我不会在异步函数中像往常一样返回新的承诺,因为 Sequelize 已经 returns 一个承诺。创建部件时,我正在等待(或者至少我认为是这样)partLibController 调用以确保在继续结构中的下一部分之前完成所有 matching/creating/joining。
非常感谢!!
递归循环
function parseChild(child, modelId, parentId, userId, level) {
return new Promise((resolve, reject) => {
partController.create({
parent_id: parentId
, name: child.name
}, { id: userId }).then((part) => {
resolve({ child: child, level: level });
if (child.children) {
child.children.forEach(grandChild => {
parseChild(grandChild, modelId, part.part_id, userId, level + '---');
});
}
}).catch(error => { console.log(error); });
}).then((obj) => { console.log(`${obj.level} ${obj.child.name}`); });
}
PartController 创建
async function create(partBody, currentUser) {
let { parent_id, name } = partBody;
const match = await partLibController.match(name);
let partLibId = null;
if (match.length == 0) {
const partLib = await partLibController.createFromPart(partBody, currentUser);
partLibId = partLib.part_lib_id;
} else {
partLibId = match[0].dataValues.part_lib_id
}
return ModelAssembly.create({
parent_id: parent_id
, name: name
, part_lib_id: partLibId
});
}
PartLibController 匹配
function match(name) {
return PartLib.findAll({
where: {
name: name
},
});
}
PartLibController CreateFromPart
function createFromPart(partBody, currentUser) {
let { name } = partBody;
return PartLib.create({
name,
});
}
感谢 AKX,我已经解决了问题:
我想问题出在递归调用本身,但这是工作代码:
async function parseChild(child, modelId, parentId, userId, level) {
const body = {
parent_id: parentId
, name: child.name
};
const ma = await partController.create(body, { id: userId });
if (child.children) {
for (const grandChild of child.children) {
await parseChild(grandChild, modelId, ma.part_id, userId, level + '---');
}
}
return;
}
我正在努力处理递归循环和嵌套的 create/select 语句。我从具有以下结构的 post 请求接收到一个对象:
11.6042
---11.6042_01
---11.6042_02
---11.6042_02
---14x10-100
------14x10-100_01
---14x10-100
------14x10-100_01
---14x10-100
------14x10-100_01
---M10-DIN929_14020
---M10-DIN929_14020
---11.6042_05
需要的行为:递归遍历结构,将记录添加到部件 table,自连接父部件,连接部件库 table,如果不存在匹配创建部件库记录并匹配创建的记录.处理下一部分。
问题:14x10-100部分在结构中出现了3次。我想在 part_lib table 中为第 14x10-100 部分创建一条记录,并引用该记录三次。实际发生的情况是,对于每个 14x10-100 部分,都会创建 part_lib table 中的相应记录,而不是一次创建和两次匹配。如果我再次 运行 它会像预期的那样匹配。我怀疑我迷失在 promise/async 等待部分代码中。
相关代码下方。为了便于阅读,我删除了一些属性映射。我的想法是:我不会在异步函数中像往常一样返回新的承诺,因为 Sequelize 已经 returns 一个承诺。创建部件时,我正在等待(或者至少我认为是这样)partLibController 调用以确保在继续结构中的下一部分之前完成所有 matching/creating/joining。
非常感谢!!
递归循环
function parseChild(child, modelId, parentId, userId, level) {
return new Promise((resolve, reject) => {
partController.create({
parent_id: parentId
, name: child.name
}, { id: userId }).then((part) => {
resolve({ child: child, level: level });
if (child.children) {
child.children.forEach(grandChild => {
parseChild(grandChild, modelId, part.part_id, userId, level + '---');
});
}
}).catch(error => { console.log(error); });
}).then((obj) => { console.log(`${obj.level} ${obj.child.name}`); });
}
PartController 创建
async function create(partBody, currentUser) {
let { parent_id, name } = partBody;
const match = await partLibController.match(name);
let partLibId = null;
if (match.length == 0) {
const partLib = await partLibController.createFromPart(partBody, currentUser);
partLibId = partLib.part_lib_id;
} else {
partLibId = match[0].dataValues.part_lib_id
}
return ModelAssembly.create({
parent_id: parent_id
, name: name
, part_lib_id: partLibId
});
}
PartLibController 匹配
function match(name) {
return PartLib.findAll({
where: {
name: name
},
});
}
PartLibController CreateFromPart
function createFromPart(partBody, currentUser) {
let { name } = partBody;
return PartLib.create({
name,
});
}
感谢 AKX,我已经解决了问题:
我想问题出在递归调用本身,但这是工作代码:
async function parseChild(child, modelId, parentId, userId, level) {
const body = {
parent_id: parentId
, name: child.name
};
const ma = await partController.create(body, { id: userId });
if (child.children) {
for (const grandChild of child.children) {
await parseChild(grandChild, modelId, ma.part_id, userId, level + '---');
}
}
return;
}