Node.js 如何以及何时使用谷歌云功能中的承诺正确返回值?

Node.js 如何以及何时使用谷歌云功能中的承诺正确返回值?,node.js,swift,google-cloud-functions,Node.js,Swift,Google Cloud Functions,我正在慢慢地浏览Node.js。我有一个基本的iOS应用程序(swift),可以将消息推送到Firestore,我正在使用Node在数据库更新时发送通知 exports.updateRequestToJoin = functions.firestore .document('/chats/{chatId}') .onUpdate(event => { if(userId != sentBy) { return db.collection('user

我正在慢慢地浏览Node.js。我有一个基本的iOS应用程序(swift),可以将消息推送到Firestore,我正在使用Node在数据库更新时发送通知

exports.updateRequestToJoin = functions.firestore
  .document('/chats/{chatId}')
  .onUpdate(event => {

    if(userId != sentBy)
    {
        return db.collection('users').doc(userId).get().then(doc => {

                var payload = {
                  notification:{
                    title: "msg",
                    body: "send msg"
                  }
                };

                admin.messaging().sendToDevice(fcm_token, payload)
                .then(function(response) {
                 // See the MessagingDevicesResponse reference documentation for
                 // the contents of response.
                 console.log("Successfully sent message:", response);
                })
                .catch(function(error) {
                 console.log("Error sending message:", error);
                });

              };

  return 0
});
最初,我只是在函数的末尾有
return
,但在我使用
return 0
之前,我得到了错误“function returned undefined,expected Promise或value”,这似乎使错误消失

我不确定的是:

  • 返回类似于0的值是否可以
  • 当错误显示“预期承诺或价值”时,承诺是否指的是
    。然后
  • 在if语句中,我返回db.collection-这是返回该值所必需的,还是可以跳过
    return
    关键字

  • 谢谢。

    这里有好问题。从函数调用者开始。您正在导出updateRequestToJoin()。打电话的人期待什么?您是否考虑使用成功或失败代码退出函数?节点应用程序的工作方式往往不同于仅返回布尔值的脚本环境。整个节点精神是关于支持一个乐于异步执行的单线程环境。因此,节点函数倾向于使用其内置的解析或拒绝方法返回承诺;或者他们运行回调

    如果您只想在then语句中返回成功代码,或在catch语句中返回失败代码,您可以执行如下简单操作:

    if(userId != sentBy)
    {
        db.collection('users').doc(userId).get().then(doc => {
    
                var payload = {
                  notification:{
                    title: "msg",
                    body: "send msg"
                  }
                };
    
                admin.messaging().sendToDevice(fcm_token, payload)
                .then(function(response) {
                 // See the MessagingDevicesResponse reference documentation for
                 // the contents of response.
                 console.log("Successfully sent message:", response);
                 return true;
                })
                .catch(function(error) {
                 console.log("Error sending message:", error);
                 return false;
                });
    
              };
    
    成功或失败将在admin.messaging链的then/catch中返回

    这是对第一个问题的回答,也是对第二个问题的部分回答。第二个问题的更完整答案需要一点阅读。是一个本机Javascript对象,它为您提供了处理异步执行的方便方法。您正在调用的db.collection链和admin.messaging链都是承诺(或某种类型的thenable构造),它们在then中返回解析,在catch中返回拒绝(您没有使用db.collection调用的catch端,但使用的是admin.messaging调用的catch端)

    最后,关于是否需要返回db.collection链,如果db.collection调用是函数调用数组的Promise.all执行的一部分,则可以这样做。但是,在本例中,您似乎只想根据admin.messaging调用的成功或失败返回成功或失败代码


    我在这里对你的目标做一些假设。至少希望这能使讨论更加清晰。

    感谢您的回复。为了澄清一下,每个then/catch都必须返回一些东西吗?不能让语句在then/catch中执行而不返回?另外re:exports.updateRequestToJoin我真正想要的是更新数据库中特定字段时要执行的云函数onUpdate方法-使用“export”是否合适?然后和catch语句不必返回值;他们只能做一些事情。作为一种做法,我要提醒大家不要这样做。良好的应用程序设计有两个目标:优雅的任务执行和清晰的消息传递。从表函数返回值可能是消息传递的一个重要部分,而消息传递反过来又支持执行流。关于节点模块导出,节点意味着在一个模块中有一个或多个导出的函数或类。这就是导入(es6)或必需模块公开其api的方式。