使用Promise时在Parse Cloud Code中返回更深层次的关系 [英] Returning deeper relations in Parse Cloud Code when using promises

查看:64
本文介绍了使用Promise时在Parse Cloud Code中返回更深层次的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

到目前为止,我已经收到一些有关Parse承诺的出色信息,并准备为我解决下一个难题...关系关系.以下代码大部分是在回答解析云代码承诺问题,但是我在下一节的代码部分的注释中有第二个问题.我将如何进一步查询顶级关系中的关系?很高兴看到您如何扩展代码以实现@ roamer-1888

I have received some excellent information on Parse promises so far and am ready to soak up the next bit of the puzzle to me... relations of relations. The following code is in most part in answering Issues with Parse Cloud Code Promises but I have in the comments of the sections piece of code my next question. How would I go about further querying of relations within the top level relations? would be great to see how you would extend you code to do that @roamer-1888

最新:

//Return a single project
Parse.Cloud.define('getProjectByUrl', function(request, response) {
    var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
    var query = new Parse.Query(Projects);
    query.equalTo('projectUrl', request.params.projectUrl);
    query.include("projectStatus"); // *MJ Added the include to add the project Status pointer
    query.find().then(function(projectsResult) {
        var project = projectsResult[0];
        //From here, `project` is hierarchically monkey-patched with the results of further queries.

        //Make tags query, the referees query and the sections query in parallel.
        var tagsPromise = project.relation('tags').query().find();
        var refereesPromise = project.relation('referees').query().find();
        var sectionsPromise = project.relation('sections').query().include("sectionType").find(); //*MJ Added the include of the sectionType pointer

        // Aggregate the three promises with Parse.Promise.when(), and handle the responses.
        return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise).then(function(tags, referees, sections) {
            project.set('tags', tags);
            project.set('referees', referees);
            project.set('sections', sections);

            //Go deeper into `sections`
            var sectionsRelationsPromises = sections.map(function(section) {
                // *MJ Remove sectionTypesPromise as it's a pointer
                var filesPromise = section.relation('files').query().include("fileType").find(); // *MJ Added the include to grab the fileType pointer
                return Parse.Promise.when(filesPromise).then(function(files) {
                    //*MJ Removed the promise for section Types
                    section.set('files', files);
                    // *MJ Removed the Deeper Logic
                });
            });
            return Parse.Promise.when(sectionsRelationsPromises);
        }).then(function() {
            return project;
        });
    }).then(function(project) {
        // At this point, all the data is gathered in the form of Parse objects in project,
        // which now needs to be mapped into a js plain object.
        var projectData = projectObj(project);
        projectData.tags = project.get('tags').map(tagObj); //Process the tags response
        projectData.referees = project.get('referees').map(refereeObj); // *MJ removed one e from refereeObj //Process the referees response
        projectData.sections = project.get('sections').map(sectionObj); //Process the sections response
        // *MJ Removed the adding of the files and looking over the sections.

        //Yay! (hopfully)
        response.success(projectData);
    }).fail(function(error) {
        response.error('Error: ' + error);
    });

    // ***********************************
    // ***** start: mapper functions *****
    // ***********************************
    function projectObj(project) {
        return { // *MJ Removed the stray equals sign here
            'id': project.id,
            'title': project.get('title'),
            'previewImage': project.get('previewImage'),
            'longDescription': project.get('longDescription'),
            'shortDescription': project.get('shortDescription'),
            'visibleToPublic': project.get('visibleToPublic'),
            'dateStart': project.get('dateStart'),
            'dateEnd': project.get('dateEnd'),
            'updatedAt': project.get('updatedAt'),
            "projectStatus": project.get("projectStatus").get("status") //*MJ Added the get of the Project Status status.
        }
    }
    function tagObj(tag) {
        return {
            'tag': tag.get('tag')
        };
    }
    function refereeObj(referee) {
        return {
            'name': referee.get('name'),
            'role': referee.get('role'),
            'emailAddress': referee.get('emailAddress'),
            'phoneNumber': referee.get('phoneNumber'),
            'linkedInUrl': referee.get('linkedInUrl')
        };
    }
    function sectionObj(section) {
        return {
            'type': section.get('sectionType').get("type"), // *MJ Added the pointer for SectionType > type
            'order': section.get('order'),
            'content': section.get('content'),
            'files': section.get('files').map(fileObj)
        };
    }
    function fileObj(file) {
        return {
            'name': file.get('name'), // *MJ chnaged the name to be more appropriate
            'url': file.get('url'), // *MJ Added the missing comma
            'type': file.get('fileType').get("type") //*MJ Added the pointer for fileType > type and removed semi colon
        };
    }
    // *********************************
    // ***** fin: mapper functions *****
    // *********************************
});

:

//Return a single project
Parse.Cloud.define('getProject', function(request, response) {
    var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
    var query = new Parse.Query(Projects);
    query.equalTo('projectUrl', request.params.projectUrl);
    query.find().then(function(projectsResult) {
        var project = projectsResult[0];
        var projectData = {
            'id': project.id,
            'title': project.get('title'),
            'previewImage': project.get('previewImage'),
            'longDescription': project.get('longDescription'),
            'shortDescription': project.get('shortDescription'),
            'visibleToPublic': project.get('visibleToPublic'),
            'dateStart': project.get('dateStart'),
            'dateEnd': project.get('dateEnd'),
            'updatedAt': project.get('updatedAt')
        };

        //Now make the tags query and the referees query in parallel.
        var tagsPromise = project.relation('tags').query().find();
        var refereesPromise = project.relation('referees').query().find();
        var sectionsPromise = project.relation('sections').query().find();
        var sectionTypesPromise = project.relation('sections').query().find().relation('type').query().find();
        var filesPromise = project.relation('sections').query().find().relation('files').query().find();
        var fileTypesPromise = project.relation('sections').query().find().relation('files').query().find().relation('type').query().find();


        // Aggregate the two promises with Parse.Promise.when(), and handle the responses.
        return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise, sectionTypesPromise, filesPromise, fileTypesPromise).then(function(tags, referees, sections, sectionTypes, files, fileTypes) {
            //Process the tags response
            projectData.tags = tags.map(function(tag) {
                return {
                    'tag': tag.get('tag')
                };
            });
            //Process the referees response
            projectData.referees = referees.map(function(refereee) {
                return {
                    'name': refereee.get('name'),
                    'role': refereee.get('role'),
                    'emailAddress': refereee.get('emailAddress'),
                    'phoneNumber': refereee.get('phoneNumber'),
                    'linkedInUrl': refereee.get('linkedInUrl')
                };
            });

            //Process the sections response
            projectData.sections = sections.map(function(section) {
                return {
                    'order': section.get('order'),
                    'content': section.get('content')
                };
            });

            // Problem: Sections have a relations column (files)
            // which I would like to return as a child of sections.
            // The files class then has a pointer column (type)
            // to another class which contains the a list of
            // file types (i.e. Image, Document, etc...)
            // The sections structure of projectDate should
            // look like:
            //
            // "sections": [{
            //   "type": "Section Type"
            //   "order": "1",
            //   "content": "This is the Section content",
            //   "files": [{
            //     "filename": "Image 1",
            //     "url": "image-1.png"
            //     "type": "Image"
            //   },
            //   {
            //     "filename": "Image 2",
            //     "url": "image-2.png",
            //     "type": "Image"
            //   },
            //   {
            //     ...
            //   }]
            //  },
            //  {
            //    ...
            //  }
            // }]

            //Process the section type response. This is reliant on sections being retrieved.
            projectData.sections.type = sections.map(function(sectionTypes) {
                return {
                    'type': sectionTypes.get('type')
                };
            });

            //Process the section files response. This is reliant on sections being retrieved.
            projectData.sections.files = sections.map(function(files) {
                return {
                    'filename': files.get('filename'),
                    'url': files.get('url')
                };
            });

            //Process the section files types response. This is reliant on files being retrieved.
            projectData.sections.files.type = sections.map(function(fileTypes) {
                return {
                    'type': fileTypes.get('type')
                };
            });
            // Currently not so Yay!

            response.success(projectData);
        });
    }).fail(function(error) {
        response.error('Error: ' + error);
    });
});

推荐答案

深入到一个层次要稍微复杂一点.每个级别都需要一个类似于顶级模式的模式.

Going deeper than one level is slightly more complicated. Each level needs a pattern much like the top level pattern.

不幸的是,这些模式并不自然地适合于扁平化".尽管可能并非绝对必要,但不断引用早期结果的需求使嵌套具有吸引力.我确定还有其他方法.

Unfortunately, these patterns don't naturally lend themselves to being "flat". The need to constantly refer back to earlier results makes nesting attractive, though probably not absolutely necessary; I'm sure that other approaches exist.

这里是尝试输入代码的地方.没有测试的方法,很可能会出错.

Here's an attempt at the code. With no means of testing it, there may well be mistakes.

//Return a single project
Parse.Cloud.define('getProject', function(request, response) {
    var Projects = Parse.Object.extend("projects"); // with credit to @kRiZ
    var query = new Parse.Query(Projects);
    query.equalTo('projectUrl', request.params.projectUrl);
    query.find().then(function(projectsResult) {
        var project = projectsResult[0];
        //From here, `project` is hierarchically monkey-patched with the results of further queries.

        //Make tags query, the referees query and the sections query in parallel.
        var tagsPromise = project.relation('tags').query().find();
        var refereesPromise = project.relation('referees').query().find();
        var sectionsPromise = project.relation('sections').query().find();

        // Aggregate the three promises with Parse.Promise.when(), and handle the responses.
        return Parse.Promise.when(tagsPromise, refereesPromise, sectionsPromise).then(function(tags, referees, sections) {
            project.set('tags', tags);
            project.set('referees', referees);
            project.set('sections', sections);

            //Go deeper into `sections`
            var sectionsRelationsPromises = sections.map(function(section) {
                var sectionTypesPromise = section.relation('type').query().find();
                var filesPromise = section.relation('files').query().find();
                return Parse.Promise.when(sectionTypesPromise, filesPromise).then(function(sectionTypes, files) {
                    section.set('type', sectionTypes[0]);
                    section.set('files', files);
                    //And deeper still into each of the section's files to find their types
                    var filesRelationsPromises = files.map(function(file) {
                        return file.relation('type').query().find().then(function(fileTypes) {
                            file.set('type', fileTypes[0]);
                        });
                    });
                    return Parse.Promise.when(filesRelationsPromises);
                });
            });
            return Parse.Promise.when(sectionsRelationsPromises);
        }).then(function() {
            return project;
        });
    }).then(function(project) {
        // At this point, all the data is gathered in the form of Parse objects in project,
        // which now needs to be mapped into a js plain object.
        var projectData = projectObj(project);
        projectData.tags = project.get('tags').map(tagObj); //Process the tags response
        projectData.referees = project.get('referees').map(refereeeObj); //Process the referees response
        projectData.sections = project.get('sections', sections).map(sectionObj); //Process the sections response
        projectData.sections.each(function(section) {
            section.files = section.get('files').map(fileObj);
        });
        //Yay! (hopfully)
        response.success(projectData);
    }).fail(function(error) {
        response.error('Error: ' + error);
    });

    // ***********************************
    // ***** start: mapper functions *****
    // ***********************************
    function projectObj(project) {
        return = {
            'id': project.id,
            'title': project.get('title'),
            'previewImage': project.get('previewImage'),
            'longDescription': project.get('longDescription'),
            'shortDescription': project.get('shortDescription'),
            'visibleToPublic': project.get('visibleToPublic'),
            'dateStart': project.get('dateStart'),
            'dateEnd': project.get('dateEnd'),
            'updatedAt': project.get('updatedAt')
        }
    }
    function tagObj(tag) {
        return {
            'tag': tag.get('tag')
        };
    }
    function refereeObj(referee) {
        return {
            'name': referee.get('name'),
            'role': referee.get('role'),
            'emailAddress': referee.get('emailAddress'),
            'phoneNumber': referee.get('phoneNumber'),
            'linkedInUrl': referee.get('linkedInUrl')
        };
    }
    function sectionObj(section) {
        return {
            'type': section.get('type'),
            'order': section.get('order'),
            'content': section.get('content'),
            'files': section.get('files').map(fileObj)
        };
    }
    function fileObj(file) {
        return {
            'filename': file.get('filename'),
            'url': file.get('url')
            'type': file.get('type');
        };
    }
    // *********************************
    // ***** fin: mapper functions *****
    // *********************************
});

我使代码尽可能地简单:

I've made the code as simple as possible to follow by :

  • 将第一个.then的回调限制为异步收集数据.
  • 在随后的.then回调中协调收集的数据的映射.
  • 最后将各个映射器功能拉到一个单独的部分中.

相信我,这比在一个块中完成所有操作更具可读性.我试过了,那简直是噩梦.

Trust me, that is more readable than doing everything in a single block. I tried that, and it was nightmarish.

调试愉快.

这篇关于使用Promise时在Parse Cloud Code中返回更深层次的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆