我有一个路由数组( recommendedRoutes ),我需要对其进行迭代并从MongoDB获取该路由的所有者( User )。从数据库中获取路由后,我会将附加的 userObj 附加到路由。
let promiseArr = [];
for (let index = 0; index < obj.recommendedRoutes.length; index++) {
console.log("Pushed: "+index);
promiseArr.push(
User.find({
_id : obj.recommendedRoutes[index].userId,
},(err,data) => {
if(err) {
console.log("Database error: " + err);
}else{
obj.recommendedRoutes[index].userObj = data[0].toObject();
console.log("Completed: "+index);
}
})
);
}
在将 userObj 附加到数组中的所有路由对象之后,我需要返回此数组。因此,我将所有查询推送到 promiseArr 中,并使用Promise.all来确保仅在所有promise解决后才返回数组。
Promise.all(promiseArr)
.then(() => {
console.log("Return Object");
return res.status(200).send({
success: true,
message: "Successfully retrieved Recommended Routes/Carpools",
obj: obj,
});
})
.catch((e) => {
throw "There was an error: "+e;
});
问题在于它有时会在promise解决之前返回数组。 预期输出:
Pushed: 0
Pushed: 1
Completed: 1
Completed: 0
Return Object
偶尔会发生什么:
Pushed: 0
Pushed: 1
Completed: 1
Return Object
Completed: 0
答案 0 :(得分:0)
您不是在使用Promises,而是在使用回调...
这是正确的方法:
import tkinter as tk
class Character:
def __init__(self, availablePoints):
self.name = ""
self.experience = 0
self.level = 0
self.gold = 0
self.stat1 = 0
self.stat2 = 0
self.stat3 = 0
self.stat4 = 0
self.stat5 = 0
self.availablePoints = availablePoints
class Game:
def __init__(self, parent):
self.myParent = parent
self.myGame = tk.Frame(parent)
self.myGame.grid()
self.statsFrame = tk.Frame(self.myGame)
self.statsFrame.grid()
self.make_stat("Strength:", "stat1", 1, 1)
def make_stat(self, text, stat, column, row):
label = tk.Label(self.statsFrame, text=text)
label.grid(column=column, row=row)
amount = tk.Label(self.statsFrame, text=getattr(myChar, stat))
amount.grid(column=(column+1), row=row)
def update():
if myChar.availablePoints >= 1:
v = getattr(myChar, stat) + 1
setattr(myChar, stat, v)
myChar.availablePoints -= 1
amount["text"] = v
button = tk.Button(self.statsFrame, text="+", command=update)
button.grid(column=(column+2), row=row)
myChar = Character(5)
root = tk.Tk()
myapp = Game(root)
root.mainloop()
答案 1 :(得分:0)
以更好的代码的名义,在开始更新recommendedRoutes
之前,请等待所有答复。
使用当前的方法,您将在相应的响应到达时立即更新各个路线对象。在这些响应之间,您的阵列处于过渡状态。它不再包含(全部)旧数据,但不再包含来自服务器的(全部)新数据。上帝禁止您的任何请求都可能失败。由于每个更新(阵列中的每个项目)都是单独处理的,因此您如何回滚或前进。
@ m1ch4ls答案也有同样的问题,它只是解决了回调的使用,而不是承诺。
恕我直言。一些更好的代码
Promise.all(
//make all the individual requests
obj.recommendedRoutes.map(
route => User.find({ _id: route.userId })
)
).then(
//and only whe they ALL have returned successfully
data => {
//update all your state at once
data.forEach((item, index) => {
obj.recommendedRoutes[index].userObj = item.toObject()
});
},
err => {
//or return an error-message if anyone fails
console.log("Database error: " + err);
}
);