10

これが私のGruntfileoutputです。

出力からわかるように、非同期タスクに関連するいくつかの問題があります。

  1. imageminが呼び出され、次のものがまっすぐ前に来ます。これにより、出力がタスクの最後に表示されます。これは非常に面倒です。
  2. buildカスタムタスクである、コマンドの終了後に使用var done = this.async()および呼び出しを行っています。done()ただし、これはタスクを単独で実行した場合にのみ正しく機能します。別のタスクで実行すると、非同期でも実行されます。
  3. build後で実行すると、jasmineテストするものが何もないため、役に立ちません。

この動作を修正する方法はありますか?

4

2 に答える 2

9

あなたの問題はこのタスクにあると思います:

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();
                    });
            }
    });

複数のフォルダーがある場合、async() と done() の両方が複数回呼び出されます。Async は単純なフラグ (true/false) として実装され、1 回呼び出されることを意図しています。最初の done() 呼び出しにより、後続のタスクを実行できます。

呼び出しを非同期に移動し、ループの外で実行する方法は多数あります。次のようなもので簡単にグーグル検索するnodejs how to callback when a series of async tasks are completeと、いくつかの追加オプションが表示されます。いくつかの簡単な(&汚れた)例:

// 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');
    }
})();

- また -

// 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');
    }
})();
于 2013-05-20T03:05:39.417 に答える