Javascript异步函数不返回
我试图过滤数组中的文档。我有一个获取用户的异步getter函数,在该函数中,如果用户与当前会话用户相同,我应该返回文档 问题是返回函数在getter中不起作用,因为它返回一个承诺。我不太了解同步和异步,但如果我像这样把它放在外面:Javascript异步函数不返回,javascript,scoping,Javascript,Scoping,我试图过滤数组中的文档。我有一个获取用户的异步getter函数,在该函数中,如果用户与当前会话用户相同,我应该返回文档 问题是返回函数在getter中不起作用,因为它返回一个承诺。我不太了解同步和异步,但如果我像这样把它放在外面: documents = documents.filter(document => { if(document.user.id != this.user.id) { return document } }) 它恢复得很好
documents = documents.filter(document => {
if(document.user.id != this.user.id) {
return document
}
})
它恢复得很好
documents = documents.filter(document => {
if(document.user.id != this.user.id) {
getter.getNextUserToSign(document.id).then(res => {
if( res != null) {
//if next user == session user
if(res.id == this.user.id){
/*This log shows*/
console.log("is equal to " + res.id)
/*but this return doesnt work*/
return document
}else{
console.log(res.id + " is not equal")
}
}else{
console.log("is null")
}
})
}
})
直到日志上写着“等于{id}”,文档才返回。正如@JClassic所说,您是从内部匿名函数返回的,而不是从主函数返回的。如果getNextUserToSign是异步的,并返回一个承诺(看起来是这样的),那么过滤器(同步的)将在第一次调用完成之前继续迭代 你可以做的是一点重构。您可以将文档数组映射到那些getNextUserToSign承诺上,然后使用Promise.all()等待所有这些承诺的解析(即完成),而不是直接过滤文档数组。然后,
Promise上的.then
回调。所有
将被传递一个数组,该数组基本上是每个文档的res
值,顺序相同,然后您可以根据其在结果数组中的对应值筛选主数组
所以像这样的重构可能看起来像这样(为了清晰起见,我拿出了你的console.logs,如果你想要的话,你可以把它们放回去):
因此,它首先过滤掉具有当前用户ID的文档,因为这不需要异步。然后,它将剩余者映射到他们的承诺。然后,当所有承诺都解决后,它会根据这些承诺的结果过滤文档数组。这不是范围问题,而是试图以同步方式处理异步操作 您正在使用一个getter,它返回一个
承诺
,这是一个异步
操作,当您希望getter返回您的文档时,它会返回一个承诺
为了解决这个问题,您可以结合使用async/await
和promises
来解析您的文档,可能是这样的
documents = documents.filter(async document => {
return await new Promise((resolve, reject) => {
if (document.user.id !== this.user.id) {
getter.getNextUserToSign(document.id).then(res => {
if (res !== null) {
if (res.id == this.$session.get("user").id) {
resolve(document);
}
}
reject(res.id + " is not equal");
});
}
});
});
不能将异步方法视为同步方法。筛选器代码不会等待异步方法完成。
res=>{
环绕您的返回语句,因此您只能从该函数中返回谢谢您的解释,我读了一些关于javascript sync的内容,但我仍然不太理解。我尝试了您的建议,但承诺中的返回仍然没有像应该的那样插入到文档中,只有第一个筛选器()正在工作。我打赌它正在工作;您是否正在尝试访问Promise回调之外的final documents数组?如果是,那就是您的问题:在Promise完成解析之前,以及在第二个筛选器运行之前,您仍在尝试访问该数组。由于您在此处有异步操作,因此在y已完成,即在内。然后
回调。
documents = documents.filter(async document => {
return await new Promise((resolve, reject) => {
if (document.user.id !== this.user.id) {
getter.getNextUserToSign(document.id).then(res => {
if (res !== null) {
if (res.id == this.$session.get("user").id) {
resolve(document);
}
}
reject(res.id + " is not equal");
});
}
});
});