将承诺的结果链接并传递给进一步的承诺[重复]
Posted
技术标签:
【中文标题】将承诺的结果链接并传递给进一步的承诺[重复]【英文标题】: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
【参考方案1】:
这在功能上与您的代码相同,只是它将credentials
传递到writeUserData
需要它的位置。不是完全平坦的承诺链,而是将 .then 添加到 createUser
响应以返回 credentials
,而不是来自 createUser
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));
【讨论】:
这将基本上并行执行login
和 createUser
- 如果您将这些函数名称表示为它们的作用,这可能会导致问题: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));
【讨论】:
以上是关于将承诺的结果链接并传递给进一步的承诺[重复]的主要内容,如果未能解决你的问题,请参考以下文章