简体   繁体   English

解析云代码承诺存在的问题

[英]Issues with Parse Cloud Code Promises

I am trying to work with Parse Cloud Code and use promises to make sure I eliminate any issues with cals being async. 我正在尝试使用Parse Cloud Code,并使用Promise来确保消除因Cals异步引起的任何问题。 I am wanting to query a class, get an object back, build up some JSON, then query some relations of the object (tags, referees) and add them to the JSON to return back for ExpressJS to render. 我想查询一个类,找回一个对象,建立一些JSON,然后查询该对象的一些关系(标签,裁判),并将它们添加到JSON中以返回ExpressJS进行渲染。 The code I paste is not working but I don't understand why if each time I am returning to project for the next promise to query on. 我粘贴的代码无法正常工作,但我不明白为什么每次我返回项目时都要查询下一个承诺。

Edit: 编辑:

//Return a single project
Parse.Cloud.define('getProject', function(request, response) {
    var projectUrl = request.params.projectUrl;

    var project;
    var projectsData = [];

    var Projects = new Parse.Object("projects");
    var query = new Parse.Query(Projects);
    query.equalTo("projectUrl", projectUrl);
    query.find().then(function(projectsResult) {
        console.log(projectsResult.length + " Projects returned");

        project = projectsResult[0];
        var projectData = {
            "id": project.get("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")
        };

        projectsData.push(projectData);
        console.log("Step 1. Projects Data: " + JSON.stringify(projectsData));

        var tagsQuery = project.relation('tags');
        return tagsQuery.query().find();
    }).then(function(tags) {
        var tagsData = [];
        for(var t = 0; t < tags.length; t++) {
            var tagData = {
                "tag": tags[t].get("tag"),
            }
            console.log("Tag Data: " + tagData);
            tagsData.push(tagData);
        }
        projectsData[tags] = tagsData;
        console.log("Step 2. Tags Data: " + JSON.stringify(tagsData));

        var refereesQuery = project.relation('referees');
        return refereesQuery.query().find();
    }).then(function(referees) {
        var refereesData = [];
        for(var r = 0; r < referees.length; r++) {
            var refereeData = {
                "name": referees[r].get("name"),
                "role": referees[r].get("role"),
                "emailAddress": referees[r].get("emailAddress"),
                "phoneNumber": referees[r].get("phoneNumber"),
                "linkedInUrl": referees[r].get("linkedInUrl"),
            }
            console.log("Referee Data: " + refereeData);
            refereesData.push(refereeData);
        }
        projectsData[referees] = refereesData;
        console.log("Step 3. Referees Data: " + JSON.stringify(refereesData));

        console.log("Everthing should be part of Projects Data here: " + JSON.stringify(projectsData));

        response.success(projectsData);
    }, function(error) {
        response.error("Error: " + error);
    });
});

The problem appears to be with your initial query. 问题似乎出在您的初始查询中。 You are trying to use subclasses, but your syntax is wrong. 您正在尝试使用子类,但是语法错误。

Your query should begin like this: 您的查询应像这样开始:

var Projects = Parse.Object.extend("projects");
var query = new Parse.Query(Projects);

EDIT: 编辑:

Also, you are returning objects, you should return promises. 同样,您正在返回对象,您应该返回承诺。 See code below (not tested): 请参见下面的代码(未经测试):

Parse.Cloud.define('getProject', function(request, response) {
    var projectUrl = request.params.projectUrl;
    var projectsData = [];

    var Projects = Parse.Object.extend("projects");
    var query = new Parse.Query(Projects);
    query.equalTo("projectUrl", projectUrl);
    query.find().then(function(projectsResult) {
        console.log(projectsResult.length + " Projects returned");

        var project = projectsResult[0];
        var projectData = {
            "id": project.get("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")
        };

        projectsData.push(projectData);
        console.log("Step 1. Projects Data: " + JSON.stringify(projectsData));

        // Removed the return from here

        var tagsData = [];
        console.log("Project Step 2: " + JSON.stringify(project));
        var tagsQuery = project.relation('tags');
        return tagsQuery.query().find();
    }).then(function(tags) {
        for(var t = 0; t < tags.length; t++) {
            var tagData = {
                "tag": tags[t].get("tag"),
            }
            tagsData.push(tagData);
        }
        projectsData.tags = tagsData;
        console.log("Step 2. Tags Data: " + JSON.stringify(tagsData));

        // Removed return from here

        var refereesData = [];
        var refereesQuery = project.relation('referees');
        return refereesQuery.find();
    }).then(function(referees) {
        for(var r = 0; r < referees.length; r++) {
            var refereeData = {
                "name": referees[r].get("name"),
                "role": referees[r].get("role"),
                "emailAddress": referees[r].get("emailAddress"),
                "phoneNumber": referees[r].get("phoneNumber"),
                "linkedInUrl": referees[r].get("linkedInUrl"),
            }
            refereesData.push(refereeData);
        }
        projectData.referees =refereesData;
        console.log("Step 3. Referees Data: " + JSON.stringify(refereesData));

        response.success(projectsData);
    }, function(error) {
        response.error("Error: " + error);
    });
});

See Parse documentation here on retrieving data using subclasses. 有关使用子类检索数据的信息,请参见此处的解析文档。

There are several issues : 有几个问题:

  • Confusion between projectsData and projectData projectsDataprojectData之间的混淆
  • projectsData isn't actually necessary. projectsData实际上不是必需的。
  • projectData needs to be in scope in the three places it is (or should be) used after it is created & assigned. projectData必须在创建和分配后在(或应)使用的三个位置范围内。
  • In several cases .then() is used where standard synchronous flow will suffice. 在某些情况下.then()用于标准同步流就足够了。 Purging the unnecessary .thens will help greatly in sorting out the scope issues. 清除不必要的.thens将大大有助于解决范围问题。

Doing little more than shuffling the code around, I arrive at the following : 除了重新整理代码之外,我所做的只是以下几点:

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.get('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')
        };

        //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();

        // Aggregate the two promises with Parse.Promise.when(), and handle the responses.
        return Parse.Promise.when(tagsPromise, refereesPromise).then(function(tags, referees) {
            //Process the tags response
            projectData.tags = tags.map(function(t) {
                return {
                    'tag': t.get('tag')
                };
            });
            //Process the referees response
            projectData.referees = referees.map(function(r) {
                return {
                    'name': r.get('name'),
                    'role': r.get('role'),
                    'emailAddress': r.get('emailAddress'),
                    'phoneNumber': r.get('phoneNumber'),
                    'linkedInUrl': r.get('linkedInUrl')
                };
            });
            // Yay!
            response.success(projectData);
        });
    }).fail(function(error) {
        response.error('Error: ' + error);
    });
});

Apart from the overall rearrangement, the only substantial changes are : 除了整体重新安排之外,唯一的重大变化是:

  • Using Array#map() to map an array to another array. 使用Array#map()将一个数组映射到另一个数组。
  • Making two queries in parallel and using Parse.Promise.when() to aggregate the two promises. 并行进行两个查询,并使用Parse.Promise.when()聚合两个promise。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM