解析云代码承诺的问题

Issues with Parse Cloud Code Promises

我正在尝试使用 Parse Cloud Code 并使用 promises 来确保我消除了异步调用的任何问题。我想查询一个 class,取回一个对象,建立一些 JSON,然后查询对象的一些关系(标签、裁判)并将它们添加到 JSON 到 return 返回以供 ExpressJS 渲染。我粘贴的代码不起作用,但我不明白为什么每次我都return计划下一个查询承诺。

编辑:

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

问题似乎出在您的初始查询上。您正在尝试使用子类,但您的语法错误。

您的查询应该这样开始:

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

编辑:

另外,你是return对象,你应该return承诺。 请参阅下面的代码(未测试):

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);
    });
});

请参阅有关使用子类检索数据的 Parse 文档 here

有几个问题:

  • 混淆projectsDataprojectData
  • projectsData 实际上没有必要。
  • projectData 需要在创建和分配后使用(或应该)使用的三个地方的范围内。
  • 在一些情况下,.then() 用于标准同步流就足够的地方。清除不必要的 .thens 将极大地帮助解决范围问题。

除了打乱代码之外,我得到了以下结果:

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);
    });
});

除了整体重新安排外,唯一实质性的变化是:

  • 使用Array#map()将一个数组映射到另一个数组。
  • 并行进行两个查询并使用 Parse.Promise.when() 聚合两个承诺。