javascript - 我需要一个 Promise 中的 Promise 及其 .then 先运行

标签 javascript node.js promise async-await es6-promise

所以,我正在阅读这个 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/

相关文章:

javascript - 将 Promise 代码从 Q 转换为 bluebird

node.js - 如何从 saveAsync 返回 Mongoose 对象?

javascript - 使用 jquery 选择器选择 optgroup 在第一次选择后停止工作

javascript - 如何在vue js中为组件添加基本动画

用于解析 : set Properly Name Is X = value # comment 的 JavaScript 正则表达式

html - 如何将普通输入 Div Post 数据发送到服务器

node.js - 为什么 client.on ("messageCreate"的 TextChannel 中缺少 nsfw 属性?

javascript - 类型错误 : Cannot read property "source" from undefined

javascript - NodeJS MongoDB 投影不工作

javascript - 如何异步调用 3 个请求?