2013-03-31 10 views
8

Oto mój Gruntfile i output.Jak sprawić, by Grunt czekał na zakończenie zadania przed uruchomieniem innego?

Jak widać na wyjściu, istnieje kilka problemów związanych z zadaniami asynchronicznych:

  1. imagemin nazywa i następny przychodzi prosto. Powoduje to, że jego wyniki pojawiają się na końcu zadań, co jest dość nieuporządkowane;
  2. , która jest niestandardowym zadaniem, jest przy użyciu var done = this.async() i wywołanie done() po zakończeniu polecenia; działa to jednak poprawnie tylko wtedy, gdy sam wykonuję zadanie; uruchomienie go z innymi zadaniami powoduje, że działa on również asynchronicznie;
  3. Z build działa później, jasmine nie ma nic do przetestowania i dlatego jest bezużyteczna.

Czy istnieje sposób naprawienia tego zachowania?

+0

Nigdy nie miałem problemów z this.async Grunt jest(). Prawdopodobnie zły efekt uboczny innego zadania? Czy próbowałeś swojego łańcucha zadań bez imagemin? –

Odpowiedz

7

wierzę, problem jest z tym zadaniem:

grunt.registerTask('prepare-dist', 'Creates folders needed for distribution', function() { 
      var folders = ['dist/css/images', 'dist/imgs/icons']; 
      for (var i in folders) { 
        var done = this.async(); 
        grunt.util.spawn({ cmd: 'mkdir', args: ['-p', folders[i]] }, function(e, result) { 
          grunt.log.writeln('Folder created'); 
          done(); 
        }); 
      } 
    }); 

Jeśli masz wiele folderów, zarówno asynchroniczny() i done() zostanie wywołana wielokrotnie. Async jest zaimplementowany jako prosta flaga (true/false) i ma być wywołana raz. Pierwsze wywołanie done() pozwala uruchomić dowolne następne zadania.

Istnieje wiele sposobów przenoszenia wywołań asynchronicznych i wykonywanych poza pętlą. Szybkie wyszukiwanie google na coś takiego: nodejs how to callback when a series of async tasks are complete dadzą ci kilka dodatkowych opcji. Kilka szybkich (& brudnych) Przykłady:

// Using a stack 
(function() { 
    var work = ['1','2','3','4','5'] 


    function loop(job) { 
     // Do some work here 
     setTimeout(function() { 
      console.log("work done"); 

      work.length ? loop(work.shift()) : done(); 
     }, 500); 
    } 

    loop(work.shift()); 

    function done() { 
     console.log('all done'); 
    } 
})(); 

- lub -

// Using a counter (in an object reference) 
(function() { 
    var counter = { num: 5 } 

    function loop() { 
     // Do some work here 
     setTimeout(function() { 
      --counter.num; 

      console.log("work done"); 

      counter.num ? loop() : done(); 
     }, 500); 
    } 

    loop(); 

    function done() { 
     console.log('all done'); 
    } 
})(); 
+0

Powiedziano mi o tym wcześniej, ale nie mam pojęcia, jak to naprawić. Jeśli przeniesiemy asynchronicznie, tworzenie folderów nastąpi wraz z innymi zadaniami. – igorsantos07

+0

Zaktualizowałem swoją odpowiedź, podając kilka przykładów wywołania zwrotnego po zakończeniu pracy. – dc5

+0

To wygląda świetnie! Chociaż od dłuższego czasu jestem poza projektem, myślę, że będzie dobrze. Wygląda na to, że deweloper naprawił też jakiś problem, który to spowodował, ale i tak odpowiedź jest dobra. Przepraszam za późną odpowiedź! – igorsantos07

0

Jak można przeczytać w Grunt documentation:

Jeśli zadanie jest asynchroniczna, to Aby wywołać oczekiwanie, należy wywołać metodę .async, aby uzyskać instrukcję Grunt. Zwraca uchwyt do "wykonanej" funkcji, która powinna być wywołana po zakończeniu zadania.

i krótki przykład byłby podobny do:

// Tell Grunt this task is asynchronous. 
var done = this.async(); 

// Your async code. 
fetchData(url).then(data => { 
    console.log(data); 
    done(); 
}).catch(error => { 
    console.err(error); 
    done(false); // false instructs Grunt that the task has failed 
}); 
Powiązane problemy