2015-03-26 2 views
1

Я пытаюсь получить идентификаторы из одного вызова с помощью мангуста. Впоследствии каждый из этих идентификаторов используется для создания другого вызова, который возвращает несколько объектов. Я пытаюсь извлечь все эти объекты.Подождите, чтобы разрешить несколько обратных вызовов

Моя текущая попытка выглядит примерно так:

var members; 
    var memberTimes = []; 

    // Use the Group model to find a specific group 
    Group.find({ 
    members: { 
     $elemMatch: { 
     $eq: req.user._id 
     } 
    }, 
    _id: req.params.group_id 
    }, function(err, group) { 
    if (err) { 
     res.send(err); 
    } else if (!group) { 
     //res.send(new Error("User not in group or it does not exist")); 
    } 

    members = group[0].members; 

    for (var member of members) { 
     // Use the Time model to find a specific time 
     Time.find({ 
     user_id: member 
     }, function(err, times) { 
     if (err) { 
      res.send(err); 
     } 

     for (var time of times) { 
      memberTimes.push(time); 
     } 
     }); 
    } 
    //on completion of all above code, execute res.json(memberTimes); 
}); 

Это, однако, не работает, потому что я не жду всех обратных вызовов от времени # находке. Я смотрю на использование обещаний, но я не уверен, как именно заставить его работать.

Кто-нибудь знает, как это можно заставить работать?

Спасибо, Daniel

ответ

1

Да, applying promises звучит неплохо.

Вам нужно будет выбрать an implementation, от которого будет зависеть how to promisify ваших вызовов find. Давайте предположим, что у вас есть find функцию, которая принимает приемник и параметры и возвращает вам обещание - (редактировать) в мангусте, вам повезет и .exec() уже, кажется, дает обещание:

function find(model, options) { 
    return model.find(options).exec(); 
} 

Тогда ваш код будет выглядеть следующим образом:

find(Group, { 
    members: {$elemMatch: {$eq: req.user._id}}, 
    _id: req.params.group_id 
}).then(function(group) { 
    if (!group) 
    throw new Error("User not in group or it does not exist"); 

    return Promise.all(group[0].members.map(function(member) { 
    return find(Time, {user_id: member}); 
    })); 
}).then(function(memberTimes) { 
    res.json(memberTimes); 
}, function(err) { 
    res.send(err); 
}); 

Здесь Promise.all это та часть, где он ждет, пока несколько раз-поиск-обещания не будут решены (параллельно).

+0

Спасибо @DVassilev за функцию 'find', хотя комментарий был бы лучше, чем предлагать редактирование (это немного изменилось для большинства рецензентов). – Bergi

+1

Без проблем, извините. Существует также небольшая ошибка с вашим кодом, поэтому я предложил изменить с исправленной версией. Спасибо. @Bergi – DVassilev

1

Вам нужно сделать асинхронный зацикливание и ждать окончательного ответа. Вы можете сделать что-то вроде

var members; 

function getTimes(mTimes, times, i, done) { 
    console.log("time " + i); 
    if (i < times.length) { 
     console.log(times[i]); 
     mTimes.push(times[i]); 
     getTimes(mTimes, times, i + 1, done); 
    } else { 
     done(mTimes); 
    } 
    } 

    function asyncLoop(memberTimes, members, i, callback) { 
    if (i < members.length) { 
     Time.find({ 
     user_id: members[i] 
     }, function(err, times) { 
     if (err) { 
      res.send(err); 
     } 
     console.log(times); 
     getTimes(memberTimes, times, 0, function(result) { 
      asyncLoop(memberTimes, members, i + 1, callback); 
     }); 
     }); 
    } else { 
     callback(memberTimes); 
    } 
    } 

    // Use the Group model to find a specific group 
    Group.find({ 
    members: { 
     $elemMatch: { 
     $eq: req.user._id 
     } 
    }, 
    _id: req.params.group_id 
    }, function(err, group) { 
    if (err) { 
     res.send(err); 
    } else if (!group) { 
     //res.send(new Error("User not in group or it does not exist")); 
    } 

    members = group[0].members; 

    var memberTimes = []; 
    asyncLoop(memberTimes, members, 0, function(memberTimes) { 
     res.json(memberTimes); 
    }); 
    }); 

приведенный выше код не может работать, потому что я не запустить его, но это, как вы можете достичь того, чего вы хотите.

+0

Спасибо, я попробую это. Является ли это рекомендуемым подходом к этим типам проблем? – DVassilev

+0

@DVassilev Я не говорю, что это рекомендуемый способ, но один из способов создания асинхронного цикла. –

+0

Я предложил изменение, которое исправляет ваш код. Спасибо. – DVassilev

Смежные вопросы