Показать сообщение отдельно
Старый 22.10.2015, 03:54   #20
moka
.
 
Регистрация: 05.08.2006
Сообщений: 10,429
Написано 3,454 полезных сообщений
(для 6,863 пользователей)
Ответ: Чат: PHP + MySQLi или что то другое?

Ой. Ты совсем не туда "пошел".

Во первых - асинхронное программирование, это концепт который ты видимо пока не понял.
Суть заключается в том что у тебя есть только один поток выполнения кода. И есть асинхронный паттерн, где ты типо говоришь: сделай А и когда будет готов ответ, вызови функцию Б.
Таким образом естественно у тебя два вызова и ответ на запрос будут обработаны сразу один за другим, не дожидаясь callback'ов.
Это не PHP, где каждый вызов блокируется - что на самом деле очень плохо.

Во первых делать API запросы которые возвращают много разной информации - очень плохо.
Лучше сделать два запроса. Таким образом в разных частях кода, когда тебе нужны будут первые или вторые данные, ты сможешь использовать уже имеющийся API route.

Пару советов по дизайну API:
1. Запросы должны быть конкретными и простыми.
2. Любой запрос должен выдавать нормальные ошибки и учитывать возможность не валидных данных от клиента.
3. Консистентный формат ответа - также помогает упростить реализацию API и клиента.

Вот пример с двумя частями.
Первая часть - это middleware для аутентификации по token'у пользователя - распространенный метод аутентификации с API. Этот токен не должен знать только клиент, и создается при аутентификации по логину паролю. Он также может иметь срок годности после последнего использования. При logout'е, token также должен удаляться.
Каждая аутентификация должна создавать свой новый token. Это по сути token клиента/сессии.
По token'у мы востанавливаем данные о пользователе. Далее имея пользователя, мы можем выполнять запрос от него.
Т.к. этот middleware загружает пользователя нам, удобно сделать список полей которые мы запрашиваем, чтобы не делать дополнительный запрос после.

Вторая часть кода, пример как получить список друзей и выслать ответ в виде JSON'а.
Подрузумевается что список ID храниться в массиве friends у пользователя.
Таким образом запросить список его друзей, очень просто.

var userAuthMiddleware = function(args) {
    var 
fields = { _id};
    if (
args.fields) {
        for(var 
0args.fields.lengthi++) {
            
fields[args.fields] = 1;
        }
    }

    return function(
reqresnext) {
        if (! 
req.query.token)
            return 
next(new Error('missing token'));

        
db.collection('auth').findOne({
            
_idreq.query.token
        
}, function(errtoken) {
            if (
err) return next(err);

            if (! 
token)
                return 
next(new Error('not authenticated'));

            
db.collection('users').findOne({
                
_idtoken.user
            
}, {
                
fieldsfields
            
}, function(erruser) {
                if (
err) return next(err);

                
// user might be not found
                
if (! user)
                    return 
next(new Error('user not found'));

                
// user logged in
                // store in req object so other middleware can access it
                
req.user user;

                
// call next middleware
                
next();
            });
        });
    }
};

// friends
app.get('/friends'userAuthMiddleware({
    
fields: [ 'friends' ]
}), function(
reqresnext) {
    
// find friends if have any
    
if (req.user.friends.length) {
        
db.collection('users').find({
            
_id: {
                
$inreq.user.friends // we store friend ids in user's array field `friends`
            
}
        }, {
            
fields: {
                
name// we need to get only their name
            
}
        }).
toArray(function(erritems) {
            if (
err) return next(err);
            
// response with array of users
            
res.json(items);
        });
    } else {
        
// if no friends, just response with empty array
        
res.json([ ]);
    }
}); 
Также лучше использовать численные ID, нежели ObjectID, т.к. они слишком большие и с ними геморойнее работать.
Также тебе нужно позаботиться в будущем о pagination - страницы, для infinite scrolling или просто системы страниц, т.к. если у кого-то слишком много друзей, грузить один большой список - это может быть не слишком хорошо.

ИМХО, ты опять спешишь, и забегаешь слишком вперед.
Старайся начинать с более простых примеров и задачек, и экспериментов.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
St_AnGer (22.10.2015)