为什么当我在 findOne 回调函数中将元素推送到数组中时,数组的值没有更新?
Why the values of array are not updating when I push elements in it in findOne callback function?
这里有两个变量,它们的值对我来说是意想不到的,我无法解决它。每当我尝试将消息对象推送到循环内的数组中时,即使变量在循环的全局范围内,变量 currentUsersMessages 的值也是一个空数组,类似地 targetUserName 正在返回 undefined 但是我可以在回调函数中访问值。
let AccountsCollection = require('../models/account')
let {PrivateChat} = require('../models/chat.model')
let messageFetchingLimit = 10;
function standardMessage(message){
let developedMessage = {
content : message.content,
content_received : message.content_received,
content_seen : message.content_seen,
sending_user : message.sending_user,
receiving_user : message.receiving_user,
delivery_date : message.delivery_date,
delivery_time : message.delivery_time,
}
if(message.attachment !== undefined){
developedMessage.attachment_url = `http://localhost:5000/chats/media/${message.attachment.file_name}`
developedMessage.attachment_type = message.attachment.file_type
}
return developedMessage;
}
router.get('/' , (req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
AccountsCollection.findOne({identifier : {publicKey : req.query.targetUserPublicKey}} , (err,success) => {
if(success){
targetUserName = success.name
}
else {
return null;
}
})
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
PrivateChat.findOne({ $and : [{'template.users' :{$in : req.query.userPublicKey}} , {'template.users' : {$in : req.query.targetUserPublicKey}}]}, async (err,usersChatObject) => {
if (usersChatObject) {
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if(userPreviousChats.length > 0){
//? IF Messages Are Less Than 10
if((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit ){
console.log('messages are less than 10')
for(let index = userPreviousChats.length - (previousMessageCount + 1) ; index >= 0; index--){
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1){
res.json({messageCount : 0})
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if(messageLeftToShow <= 10){
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey : req.query.userPublicKey,
targetUserPublicKey : req.query.targetUserPublicKey,
targetName : targetUserName,
serverSentMessageCount : `${previousMessageCount + (currentUserMessages.length)}`,
messages : currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
}
else {
res.json({error : "No Previous Messages Are Available"})
}
}
else {
console.log(err);
res.status(404).json({ error: 'Messages Record Is Not Available'})
}
})
})
这里的问题是 AccountsCollection.findOne
和 PrivateChat.findOne
都是异步的
如果你用async/await
而不是像这样的回调
来处理它会更容易
let AccountsCollection = require('../models/account')
let {
PrivateChat
} = require('../models/chat.model')
let messageFetchingLimit = 10;
router.get('/', async(req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
try {
targetUserName = await AccountsCollection.findOne({
identifier: {
publicKey: req.query.targetUserPublicKey
}
})
} catch (e) {
targetUsername = null
}
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
try {
const userChatObject = await PrivateChat.findOne({
$and: [{
'template.users': {
$in: req.query.userPublicKey
}
}, {
'template.users': {
$in: req.query.targetUserPublicKey
}
}]
})
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if (userPreviousChats.length > 0) {
//? IF Messages Are Less Than 10
if ((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit) {
console.log('messages are less than 10')
for (let index = userPreviousChats.length - (previousMessageCount + 1); index >= 0; index--) {
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1) {
res.json({
messageCount: 0
})
return;
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if (messageLeftToShow <= 10) {
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
} else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey: req.query.userPublicKey,
targetUserPublicKey: req.query.targetUserPublicKey,
targetName: targetUserName,
serverSentMessageCount: `${previousMessageCount + (currentUserMessages.length)}`,
messages: currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
} else {
res.json({
error: "No Previous Messages Are Available"
})
}
} catch (err) {
console.log(err);
res.status(404).json({
error: 'Messages Record Is Not Available'
})
}
})
这里有两个变量,它们的值对我来说是意想不到的,我无法解决它。每当我尝试将消息对象推送到循环内的数组中时,即使变量在循环的全局范围内,变量 currentUsersMessages 的值也是一个空数组,类似地 targetUserName 正在返回 undefined 但是我可以在回调函数中访问值。
let AccountsCollection = require('../models/account')
let {PrivateChat} = require('../models/chat.model')
let messageFetchingLimit = 10;
function standardMessage(message){
let developedMessage = {
content : message.content,
content_received : message.content_received,
content_seen : message.content_seen,
sending_user : message.sending_user,
receiving_user : message.receiving_user,
delivery_date : message.delivery_date,
delivery_time : message.delivery_time,
}
if(message.attachment !== undefined){
developedMessage.attachment_url = `http://localhost:5000/chats/media/${message.attachment.file_name}`
developedMessage.attachment_type = message.attachment.file_type
}
return developedMessage;
}
router.get('/' , (req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
AccountsCollection.findOne({identifier : {publicKey : req.query.targetUserPublicKey}} , (err,success) => {
if(success){
targetUserName = success.name
}
else {
return null;
}
})
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
PrivateChat.findOne({ $and : [{'template.users' :{$in : req.query.userPublicKey}} , {'template.users' : {$in : req.query.targetUserPublicKey}}]}, async (err,usersChatObject) => {
if (usersChatObject) {
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if(userPreviousChats.length > 0){
//? IF Messages Are Less Than 10
if((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit ){
console.log('messages are less than 10')
for(let index = userPreviousChats.length - (previousMessageCount + 1) ; index >= 0; index--){
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1){
res.json({messageCount : 0})
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if(messageLeftToShow <= 10){
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey : req.query.userPublicKey,
targetUserPublicKey : req.query.targetUserPublicKey,
targetName : targetUserName,
serverSentMessageCount : `${previousMessageCount + (currentUserMessages.length)}`,
messages : currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
}
else {
res.json({error : "No Previous Messages Are Available"})
}
}
else {
console.log(err);
res.status(404).json({ error: 'Messages Record Is Not Available'})
}
})
})
这里的问题是 AccountsCollection.findOne
和 PrivateChat.findOne
都是异步的
如果你用async/await
而不是像这样的回调
let AccountsCollection = require('../models/account')
let {
PrivateChat
} = require('../models/chat.model')
let messageFetchingLimit = 10;
router.get('/', async(req, res) => {
let targetUserName;
// Here We Will Find Target User Name to whom the logged in user is talking
try {
targetUserName = await AccountsCollection.findOne({
identifier: {
publicKey: req.query.targetUserPublicKey
}
})
} catch (e) {
targetUsername = null
}
// Here we will find and send previous chats of these chatting users
const previousChats = []
let currentUserMessages = []
try {
const userChatObject = await PrivateChat.findOne({
$and: [{
'template.users': {
$in: req.query.userPublicKey
}
}, {
'template.users': {
$in: req.query.targetUserPublicKey
}
}]
})
const userPreviousChats = usersChatObject.template.messages
let previousMessageCount = parseInt(req.query.nfmr)
if (userPreviousChats.length > 0) {
//? IF Messages Are Less Than 10
if ((userPreviousChats.length - previousMessageCount) <= messageFetchingLimit) {
console.log('messages are less than 10')
for (let index = userPreviousChats.length - (previousMessageCount + 1); index >= 0; index--) {
let message = await standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
console.log(message)
}
console.log(currentUserMessages)
}
//? IF Messages are not available
else if (userPreviousChats.length < 1 || userPreviousChats.length == -1) {
res.json({
messageCount: 0
})
return;
}
//? Otherwise if Messages are available and more than or equals to 10
else {
let numberOfMessages = userPreviousChats.length - 1
let messageLeftToShow = numberOfMessages - previousMessageCount
if (messageLeftToShow <= 10) {
for (let index = messageLeftToShow; index >= 0; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
} else {
// If messages are more than 10
console.log(messageLeftToShow - 10);
for (let index = messageLeftToShow; index > messageLeftToShow - 10; index--) {
let message = standardMessage(userPreviousChats[index])
currentUserMessages.push(message)
}
}
}
previousChats.push({
userPublicKey: req.query.userPublicKey,
targetUserPublicKey: req.query.targetUserPublicKey,
targetName: targetUserName,
serverSentMessageCount: `${previousMessageCount + (currentUserMessages.length)}`,
messages: currentUserMessages
})
console.log(previousChats)
res.json(previousChats)
} else {
res.json({
error: "No Previous Messages Are Available"
})
}
} catch (err) {
console.log(err);
res.status(404).json({
error: 'Messages Record Is Not Available'
})
}
})