рекурсия с обещаниями - PullRequest
0 голосов
/ 28 июня 2018

У меня есть коллекция в MongoDB, как это

[
  {
    "classId": "1",
    "name": "Input",
    "definition": [
      {
        "property": [
          {
            "classId": "12",
            "name": "One"
          },
          {
            "classId": "8",
            "name": "Comment"
          }
        ]
      }
    ]
  },
  {
    "classId": "8",
    "name": "CommentDetail",
    "definition": [
      {
        "property": [
          {
            "classId": "10",
            "name": "user"
          },
          {
            "classId": "10",
            "name": "message"
          }
        ]
      }
    ]
  },
  {
    "classId": "10",
    "name": "String",
    "definition": []
  },
  {
    "classId": "12",
    "name": "Int",
    "definition": []
  }
]

На основании вышеизложенного, у меня есть модель для отображения данные = { название:'', шаблон: '' }

При classId = 1 результат ожидания равен

   {
      "Name": "Input",
      "temlate": "{['One': 'Int','Comment': ['user': 'String','message':'String']]}"
}

Я пытаюсь использовать рекурсивное обещание для его реализации. Когда свойство [] пусто, результат будет возвращен.

Вот моя функция:

const getObjectTypeByClassId = (snapshotId, artifactId, objectType) => {

  return artifactDetailModel.find({
      'snapshotId': snapshotId,
      'artifactId': artifactId
    })
    .then(data => {
      let artifact = data[0];
      let definition;
      let definitionData = {};

      return Promise.resolve()
        .then(() => {
          definition = artifact.data.teamworks.twClass[0].definition[0];
          if (!lodash.isUndefined(definition.property)) {
            const listOfProperty = definition.property;
            for (let property of listOfProperty) {
              classId = commonUtil.getArtifactId(property.classRef[0]);
              if (!lodash.isUndefined(classId)) {
                return getObjectTypeByClassId(snapshotId, classId, objectType);
              }
            }
          } else {
            definitionData.nameType = artifact.data.teamworks.twClass[0].elementAttribute.name;
            definitionData.classId = artifact.data.teamworks.twClass[0].elementAttribute.id;
            definitionData.template = bpmMapping.objectType[artifact.data.teamworks.twClass[0].elementAttribute.name];

            return objectTypeModel.create(definitionData)
              .then(obj => {
                const response = {
                  name: objectType.name,
                  isArrayOf: objectType.isArrayOf,
                  nameType: obj.nameType,
                  template: obj.template,
                }
                return response;
              })
          }

        })
    })
}

Запустите с моей функцией, ответ

data: {
  Name: Input
  temlate: user: String,
}

Пожалуйста, посоветуйте мне.

Ответы [ 2 ]

0 голосов
/ 01 июля 2018

вот решение от парня в интернете. это работает хорошо. Спасибо @Cuong Quach

var MongoClient = require('mongodb').MongoClient;
var database = 'testdequy';
var collection = 'classes';
MongoClient.connect("mongodb://localhost:27017/" + database, function (err, db) {

    findDetails("1").then((r) => {
        console.log("r>>>", r);
    })

    function findDetails(classId) {
        var results = { Name: "", Template: "" };
        var template = {};
        return new Promise((main_resolve, reject) => {
            process(template, "" , classId)

            var works = 0;
            function process(parent, childKey, objectId) {
                return new Promise((resolve, reject) => {
                    db.collection(collection).find({ classId: objectId })
                        .toArray((err, docs) => {
                            if (results.Name == "") {
                                results.Name = docs[0].name;
                            }
                            let objectItem;
                            if (childKey == "")
                                 objectItem = parent;
                            else
                                 objectItem = parent[childKey];

                            console.log("\ndocs", docs[0], objectId, objectItem)
                            if (docs[0].definition.length == 0 || docs[0].definition[0].property == undefined) {
                                let name  = docs[0].name;
                                    parent[childKey] = name;
                                console.log("\nNo child", docs[0],parent, objectItem, docs[0].name)
                                resolve(0);

                            } else {

                                docs[0].definition[0].property.forEach((item) => {
                                    works++;
                                    //console.log("item", item)
                                    let id = item.classId;
                                    let name = item.name;
                                    objectItem[name] = {};
                                    process(objectItem, name, id).then((len)=>{
                                        works--;        
                                        if(len == 0 && works == 0) main_resolve(template);
                                    })

                                })
                                resolve(docs[0].definition[0].property.length)
                            }
                        })
                })
            }
        })

    }

});
0 голосов
/ 29 июня 2018

Я пытался до некоторой степени, но не смог сделать это правильно. Плюс ваш ожидаемый результат не является действительным JSON "temlate": {[]} не имеет смысла. Это не имеет ничего общего с Promise. Вы должны DFS, вы db массив и создали ожидаемый результат. Вот что у меня есть donup tillll сейчас, вы можете думать в том же духе. Но это далеко от решения.

let mainArray = [
    {
        "classId": "1",
        "name": "Input",
        "definition": [
            {
                "property": [
                    {
                        "classId": "12",
                        "name": "One"
                    },
                    {
                        "classId": "8",
                        "name": "Comment"
                    }
                ]
            }
        ]
    },
    {
        "classId": "8",
        "name": "CommentDetail",
        "definition": [
            {
                "property": [
                    {
                        "classId": "10",
                        "name": "user"
                    },
                    {
                        "classId": "10",
                        "name": "message"
                    }
                ]
            }
        ]
    },
    {
        "classId": "10",
        "name": "String",
        "definition": []
    },
    {
        "classId": "12",
        "name": "Int",
        "definition": []
    }
]

function dfs(root, createdRoot,  fn, level) {

    fn(root,createdRoot, level);

    if(root.definition)/*if definition exists => keep traversing*/
    root.definition[0].property.forEach(function (child) {
        createdRoot.template = createdRoot.template || [];
        let tempObj = {};
        let lookupObj = lookupByClassId(child.classId);
        tempObj[child.name] = lookupObj.name;
        createdRoot.template.push(tempObj);
        dfs(child,tempObj, fn, level + 1);
    });
    else /*if definition doesn't exist, look into the array*/
    {
        createdRoot.template = lookupByClassId(root.classId);
    }
}

function lookupByClassId(classId){
    for(let i=0;i<mainArray.length;++i){
        let element =mainArray[i]
        if(element.classId == classId)
            return element;
    }
}


let root = lookupByClassId(1);
createdRoot ={};

function func1(root, createdRoot, level) {
    createdRoot.name = root.name;
    console.log(root.classId);
}

dfs(root, createdRoot, func1, 0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...