簡體   English   中英

將“done”函數傳遞給Karma的服務器時為什么會出現gulp錯誤?

[英]Why does gulp error when passing the `done` function to Karma's server?

只寫一個(到目前為止)非常簡單的gulpfile,我遇到了一個我遇到的錯誤。

當測試因此任務失敗時,gulp會優雅地退出

gulp.task('test', done => {
    new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, () => done()).start();
});

...生產:

Chrome 50.0.2661 (Mac OS X 10.11.3): Executed 11 of 11 (3 FAILED) (0.053 secs / 0.023 secs)
[17:38:02] Finished 'test' after 2.43 s

但是當你把它縮小到剛剛done Karma時,它就會失敗而且非常失敗

gulp.task('test', done => {
    new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }, done).start();
});

...生產:

Chrome 50.0.2661 (Mac OS X 10.11.3): Executed 11 of 11 (3 FAILED) (0.066 secs / 0.042 secs)
[17:36:39] 'test' errored after 2.45 s
[17:36:39] Error: 1
    at formatError (/usr/local/lib/node_modules/gulp/bin/gulp.js:169:10)
    at Gulp.<anonymous> (/usr/local/lib/node_modules/gulp/bin/gulp.js:195:15)
    at emitOne (events.js:77:13)
    at Gulp.emit (events.js:169:7)
    at Gulp.Orchestrator._emitTaskDone (/Users/markstickley/workspace/timewarp/node_modules/gulp/node_modules/orchestrator/index.js:264:8)
    at /Users/markstickley/workspace/timewarp/node_modules/gulp/node_modules/orchestrator/index.js:275:23
    at finish (/Users/markstickley/workspace/timewarp/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:21:8)
    at cb (/Users/markstickley/workspace/timewarp/node_modules/gulp/node_modules/orchestrator/lib/runTask.js:29:3)
    at removeAllListeners (/Users/markstickley/workspace/timewarp/node_modules/karma/lib/server.js:336:7)
    at Server.<anonymous> (/Users/markstickley/workspace/timewarp/node_modules/karma/lib/server.js:347:9)
    at Server.g (events.js:260:16)
    at emitNone (events.js:72:20)
    at Server.emit (events.js:166:7)
    at emitCloseNT (net.js:1518:8)
    at doNTCallback1 (node.js:418:9)
    at process._tickCallback (node.js:340:17)

誰能解釋為什么出現這種情況,因為done是一個功能和所有封裝版本, done所做的就是調用done

進一步的研究表明,Karma通過退出代碼( https://karma-runner.github.io/0.13/dev/public-api.html )解決了傳遞給它的回調:

var Server = require('karma').Server
var server = new Server({port: 9876}, function(exitCode) {
  console.log('Karma has exited with ' + exitCode)
  process.exit(exitCode)
})

如果done傳遞除nullundefined之外的任何參數( https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulptaskname--deps-fn ),那gulp將退出運行:

gulp.task('one', function(cb) {
    // do stuff -- async or otherwise
    cb(err); // if err is not null and not undefined, the run will stop, and note that it failed
});

因此,當done直接傳遞給Karma作為回調時,Karma的退出代碼會導致gulp過早退出。 將它包裝在函數中意味着仍然調用done但沒有任何參數 - 導致正常完成。

標記,

有幾件事。

我有完全相同的問題,了解gulp對回調做了什么以及它是如何工作的。 首先,我們必須了解gulp允許您使用兩種語法。 從task任務函數和gulp返回的一個可以繼續執行后續任務,另一個必須為同一目的提供回調。 這些是等價的:

gulp.task('Returns', function(){
    return gulp.src(...).pipe(...)
})

gulp.task('Returns', function(done){
    gulp.src(...).pipe(...)
})

另一方面,javascript是一種強大的語言,它允許我們編寫一些可怕的和恐怖的誘導代碼。 出於這個原因,我喜歡把事情搞得一團糟。

將第一個函數轉換為人類可讀代碼:

步驟1

function get_karma_server(){
    return new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }
}

gulp.task('test', done => {
    get_karma_server }, () => done()).start();
});

done被定義為{}花括號內的任何內容。 逗號 但是gulp任務需要執行一個函數。 好的,執行的函數是執行get_karma_server,它返回服務器的實例和.start()

如果這不會讓你嘔吐我不知道是什么。

這就是為什么它不起作用

如果你沒有執行該函數,那么你沒有服務器的實例,這意味着start不是undefined的函數,這意味着gulp沒有得到它的回調。 因此所有與回調相關的錯誤。

第2步

function get_karma_server(){
    return new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }
}

gulp.task('test', function(done){
    get_karma_server().start();
});

仍然相當,但現在它更有意義。 完成仍然是gulp的回調。

第3步

function get_karma_server(){
    return new KarmaServer({
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    }
}

gulp.task('test', function(){
    return get_karma_server().start();
});

相同的功能,但這次我們只返回而不是提供回調,如果你不使用它。

建議

gulp.task('test', function(the_gulp_callback_aka_done){

    // Initialize and get the instance of the server
    var karma = require('karma').Server;

    // setup your configuration. This could live somewhere else
    var config = {
        configFile: __dirname + '/karma.conf.js',
        singleRun: true
    };

    // the karma callback
    function karma_Callback(){
        // Do something here after karma is done running your tests
    }

    karma.start(config, karma_Callback);
});

要冗長。 它在運行時並不慢,而且理解起來要快得多。

--------------編輯--------------

@Mark,我道歉。 我理解這個問題,但沒有傳達信息。 這不是ES5與ES6的關系。

括號()語法用於執行,對嗎? 你可以執行一些不是函數的東西,但是javascript會嘗試執行它,但是會給出錯誤而不是錯誤。

在這種情況下,您可以通過名稱提供帶有函數的業力,比如x,然后業力將通過x()獲取x和call()。 對? 這是因為它希望x在處理完測試后成為一個函數。 因此回叫。

現在,在x javascript中將執行所有內容,就像常規函數一樣,但它會遇到這個完成的事情,它不知道如何處理它因為x本身不接​​受回調。

在代碼中:

function x(){
    // get things done here
}

function x(callback_for_x){
    // get things done here

    // ok, I'm done. call the callback_for_x
    callback_for_x();
}

在此版本的x中使用完成:

function x(){
    // get things done here
    // and...
    done; // Get ready for some errors
}

在這里使用完成將工作得很好。

function x(callback_for_x){
    // get things done here

    // ok, I'm done. call the callback_for_x
    callback_for_x();
}

但是,我們將x的第一個版本作為karma的回調,這意味着我們必須手動調用done:

function x(){
    // get things done here
    // and...
    done(); // Now gulp can continue because it's callback was called.
}

我希望這更有意義。 當我語無倫次時,我討厭這個帖子已經比預期的要長了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM