我有一个服务器GET请求,我试图从一个函数创建一个承诺,但它不太顺利。我需要这个承诺是可选的,如果可能的话,那么如果结果是空的,那么它应该被忽略(我已经标记了它不应该继续使用带有IGNORE FUNCTION
字样的函数)。
这个想法是它遍历docs
内的snapshot
,并将它们添加到数组调用jamDocs
。然后,如果该数组不为空,则应遍历每个阻塞并为每个数据调用异步函数。然后设置卡纸hostName
。完成后,原始承诺应返回jamDocs
。
如果jamDocs
为空,则应忽略整个承诺。最后,在完成其他promise(有一个名为profilePromise
的返回配置文件对象)之后,应将jams分配给配置文件对象,并将对象以200状态代码发送回客户端。
我的代码:
var jamsQuery = firebase.db.collection('users')
.where("hostId", "==", id)
.orderBy("createdAt")
.limit(3)
var jamsPromise = jamsQuery.get().then(snapshot => {
var jamDocs = []
snapshot.forEach(doc => {
var jam = doc.data()
jam.id = doc.id
jamDocs.push(jam)
})
if (!snapshot.length) { // Error: Each then() should return a value or throw
return // IGNORE FUNCTION
} else {
var jamNamePromises = jamDocs.map(function(jam) {
var jamRef = firebase.db.collection('users').doc(jam.hostId)
return jamRef.get().then(doc => {
if (doc.exists) {
jam.hostName = doc.data().firstName
return jam
} else {
throw new Error("yeah")
}
})
})
Promise.all(jamNamePromises)
.then(function() {
return jamDocs
})
.catch(...)
}
})
// Later on
Promise.all(profilePromise, jamsPromise)
.then(objectArray => {
var profile = objectArray[0]
myProfile.jams = jamDocs
return res.status(200).send(myProfile);
})
.catch(
res.status(500).send("Could not retrieve profile.")
)
我收到如下错误:Each then() should return a value or throw
和Avoid nesting promises
。我该如何解决?谢谢!
答案 0 :(得分:0)
此行上的then
并未返回任何内容,并且还包含嵌套的承诺。
var jamsPromise = jamsQuery.get().then(snapshot => {
你应该重构它,然后在这之外移动嵌套的promises:
var jamsPromise = jamsQuery.get()
.then(snapshot => {
var jamDocs = []
snapshot.forEach(doc => {
var jam = doc.data()
jam.id = doc.id
jamDocs.push(jam)
})
if (!snapshot.length) {
return // IGNORE FUNCTION
} else {
var jamNamePromises = getJamDocsPromises();
return Promise.all(jamNamePromises);
})
.catch(...)
});
function getJamDocsPromises(jamDocs) {
return jamDocs.map(function(jam) {
var jamRef = firebase.db.collection('users').doc(jam.hostId)
return jamRef.get().then(doc => {
if (doc.exists) {
jam.hostName = doc.data().firstName
return jam
} else {
throw new Error("yeah")
}
});
}
答案 1 :(得分:0)
如果结果为空,则应忽略(不应继续使用该功能)。如果该数组不为空,则应该遍历每个阻塞
不要让它变得比它需要的更复杂。无论如何,循环一个空集合什么都不做,所以你不需要特殊情况。只需继续使用空数组。
var jamsPromise = jamsQuery.get().then(snapshot => {
var jamDocs = []
snapshot.forEach(doc => {
jamDocs.push(Object.assign(doc.data(), {id: doc.id}))
})
return Promise.all(jamDocs.map(function(jam) {
return firebase.db.collection('users').doc(jam.hostId).get().then(doc => {
if (doc.exists) {
jam.hostName = doc.data().firstName
return jam
} else {
throw new Error("yeah")
}
})
}))
})
我得到的错误如下:每个then()应返回一个值或抛出
您忘记了return
前面的Promise.all
。
和避免嵌套承诺。我该如何解决这个问题?
有nothing wrong with nesting promises,但在您的情况下,.then(() => jamDocs)
不是必需的,因为Promise.all
已经解析了内部承诺所满足的所有jam
的数组