所以,我正在阅读这个 XML 文件:
<GlDocumentInfo xmlns:opt="Opt.GL.Domain" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="Opt.GL.BusinessLogic">
<world version="1.0.5">
<GlDocument key="GlDocument:1">
<GlDocumentNetwork>
<Network key="Network:1">
<Paths>
<Path key="Path:1" IsEmpty="False">
<PathNodes>
<PathNode key="PathNode:1" Node="Node:1" />
<PathNode key="PathNode:2" Node="Node:15" Distance="500" />
<PathNode key="PathNode:3" Node="Node:13" Distance="320" />
<PathNode key="PathNode:4" Node="Node:4" Distance="300" />
<PathNode key="PathNode:5" Node="Node:14" Distance="450" />
</PathNodes>
</Path>
<Path key="Path:2" IsEmpty="False">
<PathNodes>
<PathNode key="PathNode:5" Node="Node:14" />
<PathNode key="PathNode:6" Node="Node:4" Distance="450" />
<PathNode key="PathNode:7" Node="Node:13" Distance="300" />
<PathNode key="PathNode:8" Node="Node:15" Distance="320" />
<PathNode key="PathNode:9" Node="Node:1" Distance="500" />
</PathNodes>
</Path>
</Paths>
</Network>
</GLDocument>
</world>
</DocumentInfo>
路径是具有这种格式的模式:var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var Path = new Schema({
key: {type: String, unique: true},
isEmpty: Boolean,
pathNodes: [String]
});
module.exports = mongoose.model('Path', Path);
PathNode 是具有以下格式的模式:var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var PathNode = new Schema({
key: String,
node: String,
distance: Number
});
module.exports = mongoose.model('PathNode', PathNode);
所以我需要阅读每个路径 Node 每个 路径 ,创建它们并将它们保存到数据库,以及将当前路径的那些路径 Node 保存在一个数组中,然后创建路径并能够将数组分配给该路径的 pathNodes 属性,该属性是那些 PathNodes 的字符串数组如你看到的。我的代码是:
var PathNode = require('../models/pathNode');
var Path = require('../models/path');
var repository = require('../../repository');
var jsonConverted = JSON.parse(convert.xml2json(req.file.buffer.toString(), { compact: true, spaces: 4, alwaysChildren: true }));
var pathNodesArray = [];
await Promise.all(jsonConverted.GlDocumentInfo.world.GlDocument.GlDocumentNetwork.Network.Paths.Path.map(async path => {
pathNodesArray = [];
await Promise.all(path.PathNodes.PathNode.map(async pathNode => {
var newPathNode = new PathNode();
newPathNode.key = pathNode._attributes.key;
newPathNode.node = pathNode._attributes.Node;
newPathNode.duration = pathNode._attributes.Duration;
newPathNode.distance = pathNode._attributes.Distance;
pathNodesArray.push(newPathNode.key);
repository.savePathNode(newPathNode);
})).then(async () => {
var newPath = new Path();
newPath.key = path._attributes.key;
newPath.isEmpty = path._attributes.IsEmpty.toString().toLowerCase();
Object.assign(newPath.pathNodes, pathNodesArray);
repository.savePath(newPath);
});
})).then(async () => {
(...) //doesn't matter for this question
}
读取工作正常,所有路径 Node 都在创建并保存在数据库中,问题是 路径:1 和 路径:2 两者都保存在相同的路径 Node 列表中,路径:1 具有来自 的 PathNode 列表路径:2 .因此,外部 Promise 中的这个 Promise 和 .then 无法正常工作,因为它正在读取所有 PathNode,然后才读取 Path,并将最后组装的 PathNode 数组分配给最后一个 Path。你能帮我解决这个问题吗,所以每个路径 有其根据路径 Node ?我试过从多个地方删除异步,等待保存...
谢谢你。
最佳答案
除了@Yevhenii 提到的问题,您的var pathNodesArray = [];
在错误的范围内。您希望每条路径都有自己的路径 Node 数组,并且在执行 pathNodesArray = [];
时如果它是顺序的,循环中可能会起作用,但在并行处理路径时它会失败。首选 const
超过 var
:
const PathNode = require('../models/pathNode');
const Path = require('../models/path');
const repository = require('../../repository');
const jsonConverted = JSON.parse(convert.xml2json(req.file.buffer.toString(), { compact: true, spaces: 4, alwaysChildren: true }));
const paths = jsonConverted.GlDocumentInfo.world.GlDocument.GlDocumentNetwork.Network.Paths.Path;
await Promise.all(paths.map(async path => {
const pathNodesArray = [];
// ^^^^^ declare inside each iteration
await Promise.all(path.PathNodes.PathNode.map(async pathNode => {
const newPathNode = new PathNode({
key: pathNode._attributes.key,
node: pathNode._attributes.Node,
duration: pathNode._attributes.Duration,
distance: pathNode._attributes.Distance,
});
pathNodesArray.push(newPathNode.key);
await repository.savePathNode(newPathNode);
// ^^^^^
}));
const newPath = new Path({
key: path._attributes.key,
isEmpty: path._attributes.IsEmpty.toString().toLowerCase(),
pathNodes: pathNodesArray,
});
await repository.savePath(newPath);
// ^^^^^
}));
// … doesn't matter for this question
关于javascript - 我需要一个 Promise 中的 Promise 及其 .then 先运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65006519/