【问题标题】:Why isn't my function returning a value from the innermost then()/catch() promises?为什么我的函数没有从最里面的 then()/catch() 承诺返回值?
【发布时间】:2021-03-06 02:21:12
【问题描述】:

下面的代码将一个文档添加到当前用户的好友集合和目标用户的好友集合中。这部分工作正常,但我在向客户端返回值时遇到问题。我已经确保客户端代码工作正常,但我对 Typescript 的理解还不够好,无法知道我在这里做错了什么。

代码当前的作用: 代码返回69和当前用户的uid。

代码需要做什么: 代码需要根据它结束的位置返回适当的返回值。在 Firebase 控制台中,我看到代码一直执行到 console.log('_addFriend Finished adding friend.') 行。之后的两行分配返回值1Friend request sent!,但客户端没有收到这些值。为什么代码不返回这些?

exports.addFriend = functions.https.onCall(async (data, context) => {
  console.log('_addFriend: ');
  const uid1 = context?.auth?.uid as string //current user 
  const targetUser = data.targetUser 
  var username1: string = ''
  var returnVal: number = 69
  var returnMsg: string = uid1 
  
  if (uid1) {
    var uid2: string;
    const currentUsersFriendsColl = 'friends_' + uid1
    await TS_doesUserExist(targetUser)
    .then(result => {
      if (result[0] == 1) {
        console.log('_addFriend: targetUser ', targetUser, ' exists.')
        uid2 = result[1]
        const targetUsersFriendsColl = 'friends_' + uid2
        TS_getUserInfo('uid', uid1, 'username')
        .then(getUserInfo_result => {
          console.log('_addFriend getUserInfo_result is about to be evaluated')
          console.log('_addFriend getUserInfo_result[0]: ', getUserInfo_result[0])
          if (getUserInfo_result[0] == 1) {
            console.log('_addFriend getUserInfo_result[0]=1')
            username1 = getUserInfo_result[1]
            //Insert into current user's friends list
            const currentUserDoc = admin.firestore().collection(currentUsersFriendsColl).doc();
            currentUserDoc.set({
              createDate: admin.firestore.FieldValue.serverTimestamp(),
              modifiedDate: admin.firestore.FieldValue.serverTimestamp(),
              stat: 2, //pending
              friendUID: uid2,
              friendUsername: targetUser,
            })
            .then(() => {
              console.log('_addFriend: About to insert into target users friends collection')
              //Insert into target user's friends list
              const friendsDoc = admin.firestore().collection(targetUsersFriendsColl).doc();
              friendsDoc.set({
                createDate: admin.firestore.FieldValue.serverTimestamp(),
                modifiedDate: admin.firestore.FieldValue.serverTimestamp(),
                stat: 2, //pending
                friendUID: uid1,
                friendUsername: username1,
              })
              .then(() => {
                console.log('_addFriend Finished adding friend.')
                returnVal = 1
                returnMsg = 'Friend request sent!'
                
              })
              .catch((error) => {
                console.log('_addFriend error adding to target users friends collec: ', error)
                returnVal = 0
                returnMsg = 'Error all the way inside: ' + error 
                
              })    
                    
            })
            .catch(error => {
              console.log('_addFriend error: ', error)
              returnVal = 0
              returnMsg = 'Error1: ' + error 
              
            })
            
          } else {
            console.log('_addFriend: In else, result was 0.')
            returnVal = 0
            returnMsg = 'Current user does not exist.'  
                     
          }
          
        })
        .catch(error => {
          console.log('_TS_getUserInfo error: ', error)
          returnVal = 0
          returnMsg = 'Could not find current user info.'
           
        })
        
      } else {
        console.log('_TS_doesUserExist: targetUser ', targetUser, ' does not exist.')
        returnVal = result[0]
        returnMsg = result[2]
        
      }
      
    })
    .catch(error => {
      console.log('_TS_doesUserExist error: ', error)
      returnVal = 0
      returnMsg = 'Error2: ' + error
      
    });
    
  }
  else {
    console.log('_addFriend error: User is not authorized');
    returnVal = 0
    returnMsg = 'User is not authorized.'
  }
  return {result: returnVal, message: returnMsg}  
});

【问题讨论】:

  • 您再次将 async/await 与 then/catch 混合在一起。这绝不是一个好主意。
  • @DougStevenson 两者之间你推荐哪一个?

标签: javascript typescript firebase google-cloud-functions


【解决方案1】:

关于您最终看到的问题,我有一个问题,控制台语句是否在客户端获得 69 和其他值之后发生?

我相信您在 TS_doesUserExist then 中调用 TS_getUserInfo 的位置可能是您的问题所在。如果您希望 TS_doesUserExist 的 await 等待它,则需要 return 该承诺链。

然后只是为了解释我相信我所看到的,如果我正确地阅读嵌套,你是:

  1. 在 TS_doesUserExist 上调用 await
  2. 主块停在那里。等待 TS_doesUserExist 处理
  3. 然后它进入 then 块并调用您的 TS_getUserInfo 函数
  4. 调用 TS_getUserInfo 函数后,来自 TS_doesUserExist 的原始承诺解析
  5. 主块继续并向客户端发送消息
  6. 主块完成允许事件循环循环回 TS_getUserInfo
  7. TS_getUserInfo 解析、输入然后块打印您的日志并分配值

因此,返回 TS_getUserInfo 应该允许它等待您的原始等待,因为它将成为 TS_doesUserExist 承诺链的一部分,并在将消息发送到客户端之前解析您的控制台和值。

我认为需要发生的事情的缩写代码示例:

exports.addFriend = functions.https.onCall(async (data, context) => { 
  const targetUser = data.targetUser; 
  var returnVal: number = 69;
  var returnMsg: string = uid1;
  
  if (uid1) {
    await TS_doesUserExist(targetUser)
      .then(result => {
        //...other code you want to process before calling TS_getUserInfo...

        // This is where I believe you need your return
        return TS_getUserInfo('uid', uid1, 'username')
          .then(() => {
            console.log('_addFriend Finished adding friend.')
            returnVal = 1
            returnMsg = 'Friend request sent!'
          });
    });
  }

  return {result: returnVal, message: returnMsg} 
});

来自 MDN 的有关 promise.then 函数的文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then

那里的链接部分也应该更深入地了解该功能。

【讨论】:

  • 我只需要单独添加关键字return还是需要添加return {result: returnVal, message: returnMsg}?我会假设前者,因为我只返回等待功能,而不是客户端,对吧?
  • 我是 TS btw 的新手,如果这是一个愚蠢的问题,我很抱歉,哈哈
  • 我在此基础上使用了一个简短的代码示例进行了编辑,但是是的,我相信你是正确的,那就是你只是返回到等待函数的那个​​地方。虽然我猜它不仅仅是 return 关键字,但你会返回你想要确保在原始 await 完成之前首先评估的承诺。在这种情况下,TS_getUserInfo 函数。
猜你喜欢
  • 2020-08-13
  • 2019-08-29
  • 2020-04-27
  • 1970-01-01
  • 2016-03-09
  • 1970-01-01
  • 2018-12-20
  • 2020-03-24
  • 2018-03-10
相关资源
最近更新 更多