ユーザーステータスがまだDBからフェッチされていない可能性があるときに応答を呼び出しているため、コードは空の結果を返す可能性があります。他の問題は、同じユーザーから複数のメッセージを受信した場合、彼のステータスの呼び出しが重複している可能性があることです。以下は、最初にユーザーの重複を避けて DB からメッセージをフェッチし、次にそのステータスを取得する関数です。
function getMessages(username, callback) {
// this would be "buffer" for senders of the messages
var users = {};
// variable for a number of total users I have - it would be used to determine
// the callback call because this function is doing async jobs
var usersCount = 0;
// helpers vars
var i = 0, user, item;
// get all the messages which recipient is "username"
db.view('privatemessages/all', {"key":username}, function (errA, resA) {
// for each of the message
resA.forEach(function (rowA) {
user = users[rowA.username];
// if user doesn't exists - add him to users list with current message
// else - add current message to existing user
if(!user) {
users[rowA.username] = {
// I guess this is the name of the sender
name: rowA.username,
// here will come his current status later
status: "",
// in this case I may only need content, so there is probably
// no need to insert whole message to array
messages: [rowA]
};
usersCount++;
} else {
user.messages.push(rowA);
}
});
// I should have all the senders with their messages
// and now I need to get their statuses
for(item in users) {
// assuming that user documents have keys based on their names
db.get(item, function(err, doc) {
i++;
// assign user status
users[item].status = doc.onlineStatus;
// when I finally fetched status of the last user, it's time to
// execute callback and rerutn my results
if(i === usersCount) {
callback(users);
}
});
}
});
}
...
getMessages(username, function(result) {
response.end(JSON.stringify(result));
});
CouchDB は優れたドキュメント データベースですが、更新のたびに完全に新しいドキュメント バージョンが作成されるため、既存のドキュメントを頻繁に更新する場合は注意が必要です (これは、高可用性とデータ耐久性を実現するために使用されるMVCCモデルのためです)。この動作の結果として、ディスク容量の消費が増加します (より多くのデータ/更新、より多くのディスク容量が必要 -例)。そのため、それを監視し、それに応じてデータベースの消費を実行する必要があります。