2016-03-27 4 views
0

Имея некоторые трудности в решении того, что должно быть простым. Я использую NodeJS и mongodb, а также использовал Bluebird для использования обещаний.NodeJS - Bluebird: дождитесь завершения цикла

У меня есть простой для цикла, где я создаю кучу случайных имен, и толкать их в массив, например:

const PlayerGenerator =() => { 
    var playerArray = [] 
    for (var i = 0; i < 15; i++) { 
     const player = new Player({ 
     name: 'Player' + Math.random() * 100 
     }) 
     playerArray.push(player) 
    } 

    return playerArray 

} 

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

server.get('api/team/new', (req, res, next) => { 
    const player = PlayerGenerator() 
    // This array contains 15 players with the exact same name. 
}) 

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

+1

Почему вы думаете, что обещания вам помогут? Обещания - это чрезвычайно общие вещи, используемые для цепочки функциональности с асинхронными действиями, такими как XHRequests. Где проблема? Вы не можете писать в свою базу данных? «const PlayerGenerator» выглядит полностью синхронно, здесь нет смысла использовать обещания. Кроме того, почему вы используете 'const', если вы собираетесь записывать эти данные в базу данных? Кроме того, обещания в значительной степени полностью реализованы в узле ES6 +, зачем беспокоиться о том, что вы можете злоупотреблять вещами с помощью библиотеки Bluebird? – ajxs

+1

Быть немного более кратким * «Здесь нет асинхронного кода» *. Поэтому «возможно» ваши объекты «Player» требуют фактического создания в базе данных, и вы хотите вернуться только после их создания. Это то, что вы просите здесь? Поскольку 'new Player()' не предполагается асинхронным методом. Если, конечно, вы не скрываете того, о чем мы не знаем. По моей «догадке» заключается в том, что это всего лишь образец модели мангуста. Так что не aync. Все же! –

ответ

1

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

Все, что вам действительно нужно сделать, это «создать 15 случайно назвали игроков в базе данных» и сторонясь лучшие методы, чтобы получить уникальные случайные имена (потому что текущий метод не является «уникальным» случайным образом), все, что вы на самом деле нужно сделать, это передать массив простых объектов непосредственно Player.create(), так как ваша история на этом говорит, что вы используете мангуст все равно:

Player.create(
    Array.apply(null,Array(15)).map(() => { 
    return { "name": "Player" + Math.floor(Math.random() * 100) } 
    }) 
).then((players) => { 
    console.log(players) 
}); 

Что только собираюсь дать вам выход что-то вроде:

[ { _id: 56f7488242727e6c308f79eb, name: 'Player87', __v: 0 }, 
    { _id: 56f7488242727e6c308f79ec, name: 'Player29', __v: 0 }, 
    { _id: 56f7488242727e6c308f79ed, name: 'Player81', __v: 0 }, 
    { _id: 56f7488242727e6c308f79ee, name: 'Player52', __v: 0 }, 
    { _id: 56f7488242727e6c308f79ef, name: 'Player12', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f0, name: 'Player93', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f1, name: 'Player69', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f2, name: 'Player88', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f3, name: 'Player81', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f4, name: 'Player48', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f5, name: 'Player38', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f6, name: 'Player82', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f7, name: 'Player47', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f8, name: 'Player85', __v: 0 }, 
    { _id: 56f7488242727e6c308f79f9, name: 'Player26', __v: 0 } ] 

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

Конечно, если вы просто хотите сыграть с обещанием, то просто используйте Promise.all(), что также не обязательно нужно включать Bluebird здесь, особенно если вы уже работаете с конструкциями ES6.

Просто возвратите Promise из .create(), а затем решить позже:

var playerPromises = Array.apply(null,Array(15)).map(() => { 
    return Player.create({ "name": "Player" + Math.floor(Math.random() * 100) }); 
    }); 

    Promise.all(playerPromises).then((players) => { 
     console.log(players); 
    }); 

Так что в этом случае вы просто с помощью Promise возвращенное .create() и разрешения каждого в результирующем массиве. Но, конечно, он действительно пишет в базу данных «пятнадцать раз», когда вы могли отправить только «один» запрос вместо этого.

Для моих двух центов просто поставьте массив вещей, которые вы хотите создать, прямо на .create(). Несмотря на то, что для решения множества обещаний существуют варианты использования, это действительно не тот, в котором это наиболее оптимальное решение.

+0

Отличный ответ, спасибо! –