异步函数返回 Promise <Pending>
Posted
技术标签:
【中文标题】异步函数返回 Promise <Pending>【英文标题】:async function returns Promise <Pending> 【发布时间】:2020-07-09 10:44:24 【问题描述】:我正在为一个项目构建一个 crud 应用程序, 人们可以添加查看和删除条目,我为此使用了 nodejs、js 和 fireabse。 我有这样一个 Firestore 数据库结构:
entries:
--entry id
--entry data
users:
--user id
--user email (query)
-- my entries (collection)
-- entries id
--entry id
现在我想显示所有用户条目, 所以我创建了这个 module.exports 函数:
module.exports =
//get all the users entries from database with passed in uid ('/dashboard')
getUserEntries: async uid =>
//get all his entries docs id from "myEntries" collection in an, array
const usersEntriesId = await db
.collection("users")
.doc(uid)
.collection("myEntries")
.get()
.then(entries =>
return entries.docs.map(entry => entry.data().entry);
)
.catch(err => console.log(err));
console.log(usersEntriesId); //works fine, logs array with ids
const userEntriesDocs = usersEntriesId.map(async id =>
const entry = await db
.collection("entries")
.doc(id)
.get()
.then(entry =>
return entry.data();
);
console.log("hello:", entry); //works fine returns logs entry data
return entry;
);
console.log("hello1: ", userEntriesDocs); //doesnt work i get "hello1: [ Promise <pending> ,
// Promise <pending> ,
//Promise <pending> ]"
//i got three entries, that's why i get 3 times "Promise <pending> "
;
那我该如何解决呢?
谢谢
【问题讨论】:
这就是应该发生的事情。如果你想要一个 promise 解析的值,等待它或使用 .then。 【参考方案1】:好吧,async
函数返回 Promise
,这就是它们在后台的工作方式。如果没有.map
,您可以只在该函数上使用await
,或者将其用作任意Promise
与.then()
和.catch
。但由于存在Promise
数组,您需要Promise.all
等到所有问题都解决。
const userEntriesDocs = await Promise.all(usersEntriesId.map(async id =>
....
);
注意:与.allSettled
不同,如果任何后续Promise
失败,.all()
将立即失败。因此,如果您出于任何原因想要从成功的请求中获取数据,则需要更复杂的逻辑。
您也可以手动执行循环:
const userEntriesDocs = [];
for(const docPromise of userEntriesId.map(.....))
userEntriesDocs.push(await docPromise);
但对我来说await Promise.all[...]
更具可读性。
我还强调了 Promises 数组(请求已经发送)。如果您尝试发送请求在循环内喜欢
const userEntriesDocs = [];
for(const id of userEntriesId)
userEntriesDocs.push(await db
.collection("entries")
.doc(id)
.get()
.then(entry =>
return entry.data();
)
);
您会发现请求是严格逐个进行的,而不是并行进行的。这将需要更多时间来处理列表。
【讨论】:
我认为您在Promise.all()
之前缺少await
。没有它,userEntriesDocs
本身就是一个承诺。
是的,谢谢你们,所以如果我在一个函数中有几个承诺,我需要使用 Promise.all()?是否可以通过更多的异步等待行来实现它?
@MendiSterenfeld 唯一的选择是在其中使用循环和await
。我已经在该方法上添加了示例。以上是关于异步函数返回 Promise <Pending>的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的异步函数返回 Promise <pending> 而不是一个值?