2014-11-13 5 views
1

Итак, я несколько раз избивал это в течение нескольких дней, и я в тупике, что является лучшим способом его решения. Я использую ватерлинию/dogwater с HAPI и пытаюсь сделать что-то в широком смысле, как так: -Выполнение асинхронной операции в обещании bluebird

wardrobe.find({WardrobeId: 5}).then(function(clothes) { 
    //got my clothes in my wardrobe. 
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) { 
     //got my nice trousers 
     _.each(trousers, function(trouser) { 
      //logic to see if these are my pink trousers 
      console.log('color?', trouser.color); 
     }); 
     console.log('ding'); 
    }); 
}); 

Проблема у меня есть код всегда будет ding перед выводом цвета брюк. Это потому, что, насколько я понимаю, _.each сделает код асинхронным. Я пытался ввести Promises (bluebird), но без везения. Я даже посмотрел на генераторы (Co), но моя версия узла исправлена ​​в pre v0.11.

Я хотел бы выполнить некоторые окна просмотра базы данных в _.each, вернуть эти результаты (если таковые имеются) к объекту брючный, который затем может быть возвращен: -

wardrobe.find({WardrobeId: 5}).then(function(clothes) { 
    //got my clothes in my wardrobe. 
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) { 
     //got my nice trousers 
     _.each(trousers, function(trouser) { 
      //logic to see if these are my pink trousers 
      db.colors.find({Color: trouser.color}).then(function(color) { 
       //color here? 
      }); 
     }); 
     console.log('ding'); 
    }); 
}); 

Что является лучшим способом сделать это максимально эффективно?

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

+0

Вы можете используйте код asynchrounus js, как блокирующий код, используя функции ecmascript 6. Взгляните на Task.js (http://taskjs.org/), но я не уверен, поддерживает ли ваша среда js эти es6 apis. –

+0

Предполагая подчеркнуть/lodash - _.each не async. –

+0

@BenjaminGruenbaum Но db.colors.find, кажется, возвращает обещание, которое делает все асинхронным. Если 'yield' доступен, вы можете использовать Task.js для выполнения этого обещания до тех пор, пока он выполняется. –

ответ

5

Ну _.each не имеет отношения к асинхронности. Это просто способ подчеркнуть/lodash сделать trousers.forEach(...).

Ваша проблема связана с методом db.colors.find, который выполняет асинхронную операцию. Вы можете приковать методы, если вы хотите, чтобы выполнить последовательно, как, например:

wardrobe.find({WardrobeId: 5}).then(function(clothes) { 
    //got my clothes in my wardrobe. 
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) { 
     //got my nice trousers 
     var p = Promise.resolve(); 
     _.each(trousers, function(trouser) { 
      //logic to see if these are my pink trousers 
      p = p.then(function() { 
       return db.colors.find({Color: trouser.color}) 
        .then(function(color) { 
         // color here, they'll execute one by one 
        }); 
      }); 
     }); 
     p.then(function(){ 
      console.log('ding, this is the last one'); 
     }); 
    }); 
}); 

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

wardrobe.find({WardrobeId: 5}).then(function(clothes) { 
    //got my clothes in my wardrobe. 
    clothes.find({Type: 'trousers'},{Kind: 'nice ones'}).then(function(trousers) { 
     //got my nice trousers 
     Promise.map(trousers, function(trouser) { 
      return db.colors.find({Color: trouser.color}); 
     }).map(function(color){ 
      console.log("color", color); 
     }).then(function(){ 
      console.log('ding, this is the last one'); 
     }); 
    }); 
}); 
+0

Spot on Benjamin. Спасибо. +1 – dooburt

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