【问题标题】:Issues with Parse Cloud Code PromisesParse Cloud 代码承诺的问题
【发布时间】:2015-12-07 17:55:16
【问题描述】:

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

编辑:

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

【问题讨论】:

    标签: javascript json parse-platform promise parse-cloud-code


    【解决方案1】:

    有几个问题:

    • 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() 聚合两个 Promise。

    【讨论】:

    • 这非常有效@Roamer-1888。现在我只需要弄清楚如何查询不同的类并添加到我的数据集/
    • 马克,如果第三个查询只依赖于promise,那么我的模式应该很好地扩展以适应它。只需添加另一个var xxxxPromise = project.relation... 语句,将xxxxPromise 添加到Parse.Promise.when(...),并以与tagsreferees 相同/相似的方式处理响应。
    • 所以我想我听从了你的建议,但没有得到我希望的人口。我还尝试链接承诺以进行更深入的查询,即,但这也不起作用。我已经在后续问题stackoverflow.com/questions/34146245/… 上更新了我的代码
    【解决方案2】:

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

    您的查询应该这样开始:

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

    编辑:

    另外,你正在返回对象,你应该返回 Promise。 请参阅下面的代码(未测试):

    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,了解如何使用子类检索数据。

    【讨论】:

    • 当所有关于 Parse Cloud Code 的最新消息都在谈论使用 Promises 而所有文档都使用回调时,这非常令人沮丧。这是一个混杂的信息,很难找到有用的例子。我更改了上面的代码,但仍然无法正常工作。我得到的错误是:`结果:TypeError:无法调用未定义的方法“关系”`
    • 是的,他们的文档没有更新。错误很好,这意味着您的承诺正在发挥作用。该错误意味着您的对象为空(未定义)。
    • 见上面的更新。您正在返回实际对象,应该返回承诺。虽然代码未经测试,但应该给出一个大致的概念。
    • 所以经过一些编辑后,我得到了以下所有 console.logs 打印我所期望的工作,但我无法检查我希望拥有所有完整 JSON 的最后一个,包括我要添加的标签和裁判,所以我不确定它是否有效。从 API 控制台向我显示的内容来看,情况似乎并非如此,因为它似乎只返回了第一个承诺的数据。
    • 感谢您的帮助 @kRiZ 我从您的回复中了解了一些有关承诺的信息,我很感激。
    猜你喜欢
    • 2019-08-29
    • 2020-11-15
    • 2017-05-17
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 2017-03-21
    • 1970-01-01
    相关资源
    最近更新 更多