【问题标题】:Chaining and passing result of promise to a promise further down [duplicate]将承诺的结果链接并传递给进一步的承诺[重复]
【发布时间】:2017-11-28 08:16:02
【问题描述】:

我正在链接一些返回承诺的请求。第一个是对某个站点的登录检查,该站点返回一些凭据。然后我打了一个 admin.auth().createUser() 电话。在我知道这个 createUser 调用成功并且我知道登录检查成功之后,我想使用从两个 promise 返回的这两个对象来发出第三个请求,以将信息存储在 firebase 实时数据库中。我只是不知道如何将这两个结果传递给最终的承诺。这是一些代码。

login(siteUser, sitePass)
   .then(credentials => {
      return admin.auth().createUser({
         'email': email,
         'emailVerified': false,
         'password': password,
         'displayName': username
       })
    })
    .then(userData => {
       return writeUserData(userData, credentials); // I need to pass credentials here but I don't know how.
    })
    .then(() => res.status(200).send('success'))
    .catch(err => res.status(500).send(err));

我需要在 createUser() 解析后将第一个承诺的结果传递给 writeUserData。

【问题讨论】:

  • userRecord 中的 writeUserData(userRecord, credentials) 是什么?为什么userData 被忽略?你不需要createUser的结果吗?
  • 呜呜它应该是 userData

标签: node.js firebase firebase-realtime-database promise chaining


【解决方案1】:

这在功能上与您的代码相同,只是它将credentials 传递到writeUserData 需要它的位置。不是完全平坦的承诺链,而是将 .then 添加到 createUser 响应以返回 credentials,而不是来自 createUser

unused(在您的代码中)响应
login(siteUser, sitePass)
.then(credentials => 
    admin.auth().createUser({
        email, 
        emailVerified:false, 
        password, 
        displayName: username
    })
    .then(userData => credentials)
)
.then(credentials => writeUserData(userRecord, credentials))
.then(() => res.status(200).send('success'))
.catch(err => res.status(500).send(err));

但是,如果您在代码中犯了错误并且

.then(userData => {
   return writeUserData(userRecord, credentials); // I need to pass credentials here but I don't know how.
})

应该是

.then(userData => {
   return writeUserData(userData, credentials); // I need to pass credentials here but I don't know how.
})

(即 userRecord 应该是 userData) - 那么您不会忽略来自 createUser 的响应 - 这根本不会使代码变得更加复杂

login(siteUser, sitePass)
.then(credentials => 
    admin.auth().createUser({
        email, 
        emailVerified:false, 
        password, 
        displayName: username
    })
    .then(userData => ({userData, credentials}))
)
.then(({userData, credentials}) => writeUserData(userData, credentials))
.then(() => res.status(200).send('success'))
.catch(err => res.status(500).send(err));

【讨论】:

  • 谢谢!是的,这是一个错字
  • 酷,所以最后一个代码块应该可以工作
  • 这没有按原样工作。我需要在 admin.auth 之前添加 return。喜欢@shivam 的解决方案
  • 在这种情况下,您错误地复制了代码,返回时会出现语法错误,因为我使用的是具有隐式 return 的速记箭头函数符号 - 请注意完全缺少 @ 987654332@=>之后的@
  • 哦,我现在明白了。还有一件事。如何从返回的 admin.auth().createUser() 中正确捕获错误?如果我只是添加一个 catch 并尝试执行 res.send(err),那么外部就会被执行。如何在内部 catch 中完成调用或将 catch 传递给外部?
【解决方案2】:

你可以试试这个。你需要使用Promise.all

const loginPromise = login(siteUser, sitePass);
const createUserPromise = admin.auth().createUser({
  'email': email,
  'emailVerified': false,
  'password': password,
  'displayName': username
})

Promise.all([loginPromise, createUserPromise]).then(result => {
    // Then use result array
    return writeUserData(result[1], result[0]);
  }).then(() => res.status(200).send('success'))
  .catch(err => res.status(500).send(err));

【讨论】:

  • 这将基本上并行执行 logincreateUser - 如果您将这些函数名称表示为它们的作用,这可能会导致问题:p
【解决方案3】:

Maaz 的 Promise.all 解决方案也可以使用,除非您需要从登录请求到 createUser 请求中的某些内容。如果是这样,那么您可以使用下面的解决方案。

login(siteUser, sitePass)
.then(credentials => {
  return admin.auth().createUser({
     'email': email,
     'emailVerified': false,
     'password': password,
     'displayName': username
   })
  .then(createUserRes => ({createUserRes, credentials})
})
.then(userData => {
    // You can now access both the createUserRes & credentials as
    // userData.credentials or userData.createUserRes
   return writeUserData(userRecord, credentials); // I need to pass credentials here but I don't know how.
})
.then(() => res.status(200).send('success'))
.catch(err => res.status(500).send(err));

【讨论】:

    猜你喜欢
    • 2017-08-04
    • 2021-02-18
    • 1970-01-01
    • 2017-10-18
    • 2016-01-05
    • 2018-04-22
    • 2013-12-08
    • 2018-03-18
    • 1970-01-01
    相关资源
    最近更新 更多