2016-03-16 2 views
2

Я пытаюсь запустить async.each по массиву элементов.async.waterfall внутри async.each не работает?

Для каждого элемента, я хочу запустить async.waterfall. См. Код ниже.

var ids = [1, 2]; 

async.each(ids, 

    function (id, callback) { 

     console.log('running waterfall...'); 

     async.waterfall([ 

      function (next) { 

       console.log('running waterfall function 1...'); 

       next(); 
      }, 

      function (next) { 

       console.log('running waterfall function 2...'); 

       next(); 
      }], 

      function (err) { 

       if (err) { 
        console.error(err); 
       } 
       else { 
        console.log('waterfall completed successfully!'); 
       } 

       callback(); 
      }); 
    }, 

    function (err) { 

     if (err) { 
      console.error(err); 
     } 
     else { 
      console.log('each completed successfully!'); 
     } 

    }); 

return; 

Выход для этого кода выглядит следующим образом:

running waterfall... 
running waterfall function 1... 
running waterfall... 
running waterfall function 1... 
running waterfall function 2... 
running waterfall function 2... 
waterfall completed successfully! 
waterfall completed successfully! 
each completed successfully! 

Но мое намерение и я понимаю, что результат должен выглядеть следующим образом:

running waterfall... 
running waterfall function 1... 
running waterfall function 2... 
waterfall completed successfully! 
running waterfall... 
running waterfall function 1... 
running waterfall function 2... 
waterfall completed successfully! 
each completed successfully! 

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

Спасибо!

ответ

4

async.each() пытается запустить все итерации цикла параллельно, поэтому все итерации могут одновременно выполняться в полете и будут выполняться в неопределенном порядке. Вы можете это ясно увидеть в doc for .each():

Применяет функцию итерации к каждому элементу в arr параллельно. Итерация вызывается с элементом из списка и обратным вызовом, когда он закончил. Если итератор передает ошибку в свой обратный вызов, основной обратный вызов (для каждой функции) немедленно вызывается с ошибкой .

Обратите внимание, что, поскольку эта функция применяет итерацию к каждому элементу в параллельно, нет гарантии, что итерационные функции будут в полном порядке.

Итак, это объясняет, почему итерации .waterfall() идут в то же время, а не серийно.

Если вы хотите запускать их один за другим, то вместо этого вы должны использовать async.eachSeries().

+0

Спасибо @ jfriend00. отличный ответ – fooser

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