使用带有 Promises 的嵌套云代码函数时出现 ParseError

Posted

技术标签:

【中文标题】使用带有 Promises 的嵌套云代码函数时出现 ParseError【英文标题】:ParseError when using Nested Cloud Code functions with Promises 【发布时间】:2020-05-14 05:54:58 【问题描述】:

我需要帮助,因为我对 Promises 和使用 Cloud Code 有点陌生。我已经在 *** 上检查了其他问题,但使用已弃用的 Parse.Promise 类似乎都已过时。

注意:我正在使用本地安装的解析服务器,以便能够更轻松地测试我的云代码。

我有 2 个功能。

Parse.Cloud.define("getTag", async (request) => 
Parse.Cloud.define("createTag", async (request) => 

基本上,我调用 getTag 传递一个字符串。该函数检查标签是否存在,然后返回它。如果没有,它通过调用 createTag 函数创建标签,然后返回新的 Tag 对象。

不管怎样,我应该得到一个 Tag 对象。

我的 getTag 函数工作正常并返回现有对象。但是我被卡住了,无法从 createTag 函数中获取新创建的 Tag 对象以传递/返回到 getTag 函数。

即使标签已正确创建并在我检查数据库时按预期结束在标签类中,我也会收到以下错误:

ParseError: The server returned an invalid response.
    at <path>/node_modules/parse-server/node_modules/parse/lib/node/Cloud.js:163:13
at processTicksAndRejections (internal/process/task_queues.js:97:5) 
  code: 107

基本上我不确定我是否正确地从 createTag 返回了对象。

这是我的 2 个函数。任何帮助,将不胜感激。

Parse.Cloud.define("getTag", async (request) => 
    console.log("===== Begin getTag ====== \n\n\n")

    const Tag = Parse.Object.extend("Tag");
    const query = new Parse.Query(Tag);

    query.equalTo("tag", request.params.tag);
    await query.first().then(
        function(foundTag) 
            // Check if we got an object back.
            if (foundTag === undefined || foundTag === null) 
                // We have to create a new one.
                console.log("NO TAG FOUND:\nLet's create a new tag with - ", request.params.tag)    
                Parse.Cloud.run("createTag", tag: request.params.tag).then(function(createdTag) 

// PROBLEM IS HERE - I CAN'T get createdTag object.

                    return createdTag;
                )
                .catch(function(error) 
                    // There was an error.
                    console.log(error)
                    return error
                );
             else 
                // We found an existing Tag Object
                console.log("Found an EXISTING TAG:", foundTag);
                console.log("\n\n\n")

                return foundTag;        
            
        ).catch(function(error) 
            // There was an error.
            console.log(error)
            return error
        );
);

Parse.Cloud.define("createTag", async (request) => 
    console.log("n\n ===== Begin createTag ====== \n\n\n")

    var tagString = request.params.tag
    const TagClass = Parse.Object.extend("Tag");
    const Tag = new TagClass();
    Tag.set("tag", tagString);
    const results = await Tag.save().then(function(newTag) 
        // Execute any logic that should take place after the object is saved.
        console.log("TAG CREATED:", newTag);
        console.log("\n\n\n")
/* 
THIS WORKS FINE. newTag object prints out
TAG CREATED: ParseObjectSubclass 
  className: 'Tag',
  _objCount: 3,
  id: 'DOaiQGuzLB'

*/
        return newTag;
    )
    .catch(function(error) 
        // There was an error.
        console.log(error)
        return error
    );
);

这是 Cloud.js 163 中的行

  throw new _ParseError.default(_ParseError.default.INVALID_JSON, 'The server returned an invalid response.');

【问题讨论】:

【参考方案1】:

我终于明白了,这是一个悲伤的问题。

这一切都归结为我不了解 .then 和 async 函数如何工作的结构。我假设 .then() 中的返回意味着整个函数的返回。当我发现它不是时,链接返回函数就是解决方案。

我的 Parse.cloud.run("createTag") 函数本身没有返回对象,这就是它返回 undefined 到 getTag 函数的原因。

解决方案只是在 createTag 函数的末尾添加“返回结果”。

Parse.Cloud.define("createTag", async (request) => 
    console.log("n\n ===== Begin createTag ====== \n\n\n")

    var tagString = request.params.tag
    const TagClass = Parse.Object.extend("Tag");
    const Tag = new TagClass();
    Tag.set("tag", tagString);
    const results = await Tag.save().then(function(newTag) 
        // Execute any logic that should take place after the object is saved.
        console.log("TAG CREATED:", newTag);
        console.log("\n\n\n")

        return newTag;
    )
    .catch(function(error) 
        // There was an error.
        console.log(error)
        return error
    );

// ADDED THIS
return results
);

至少现在我对 async 和 Promise 的工作原理有了更好的理解。我希望这可以在将来节省像我这样的其他新手开发人员。

【讨论】:

以上是关于使用带有 Promises 的嵌套云代码函数时出现 ParseError的主要内容,如果未能解决你的问题,请参考以下文章

使用 Typescript 创建 Firebase 云函数时出现“找不到名称‘ServiceWorkerRegistration’”错误

你能避免使用 Promises 完全嵌套吗? [复制]

Node.js assert.throws 带有异步函数(Promises)

使用Fetch&promises实现数据交互

带有 JavaScript 函数的 Async-Await 或 Promises [关闭]

为具有嵌套标签的自定义标签编写 jekyll 插件时出现问题