Issues with Parse Cloud Code Promises

橙三吉。 提交于 2019-12-14 02:59:38

问题


I am trying to work with Parse Cloud Code and use promises to make sure I eliminate any issues with cals being async. 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. 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);
    });
});

回答1:


There are several issues :

  • Confusion between projectsData and projectData
  • projectsData isn't actually necessary.
  • projectData needs to be in scope in the three places it is (or should be) used after it is created & assigned.
  • In several cases .then() is used where standard synchronous flow will suffice. Purging the unnecessary .thens will help greatly in sorting out the scope issues.

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.
  • Making two queries in parallel and using Parse.Promise.when() to aggregate the two promises.



回答2:


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.



来源:https://stackoverflow.com/questions/34124443/issues-with-parse-cloud-code-promises

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!