简体   繁体   English

将“done”函数传递给Karma的服务器时为什么会出现gulp错误?

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

Just writing a (so far) very simple gulpfile and I am perplexed by an error I have come across. 只写一个(到目前为止)非常简单的gulpfile,我遇到了一个我遇到的错误。

When the tests fail with this task, gulp exits gracefully 当测试因此任务失败时,gulp会优雅地退出

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

...produces: ...生产:

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

But when you slim it down to just pass done into Karma, it fails rather ungracefully 但是当你把它缩小到刚刚done Karma时,它就会失败而且非常失败

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

...produces: ...生产:

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)

Can anyone explain why this happens, given that done is a function and all the wrapped version of done does is call done ? 谁能解释为什么出现这种情况,因为done是一个功能和所有封装版本, done所做的就是调用done

Further research has revealed that Karma resolves the callback passed to it with an exit code ( https://karma-runner.github.io/0.13/dev/public-api.html ): 进一步的研究表明,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)
})

And that gulp will quit the run if done is passed any argument other than null or undefined ( https://github.com/gulpjs/gulp/blob/master/docs/API.md#gulptaskname--deps-fn ): 如果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
});

So Karma's exit code is causing gulp to exit prematurely when done is passed directly to Karma as a callback. 因此,当done直接传递给Karma作为回调时,Karma的退出代码会导致gulp过早退出。 Wrapping it in a function means that done is still called but without any arguments -- causing normal completion. 将它包装在函数中意味着仍然调用done但没有任何参数 - 导致正常完成。

Mark, 标记,

A couple of things. 有几件事。

I had exactly the same issue understanding what gulp was doing with the callback and how it all worked. 我有完全相同的问题,了解gulp对回调做了什么以及它是如何工作的。 First and foremost we must understand that gulp allows you to have two syntaxes. 首先,我们必须了解gulp允许您使用两种语法。 One where you return from the task function and gulp can get on with its subsequent tasks, and the other where you must provide a callback for the same purpose. 从task任务函数和gulp返回的一个可以继续执行后续任务,另一个必须为同一目的提供回调。 These are equivalent: 这些是等价的:

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

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

On the other hand javascript being the powerful language that it is allows us to write some horrific and terror inducing code. 另一方面,javascript是一种强大的语言,它允许我们编写一些可怕的和恐怖的诱导代码。 For that reason I like to break things down a little. 出于这个原因,我喜欢把事情搞得一团糟。

Translating the first function into human readable code: 将第一个函数转换为人类可读代码:

Step 1 步骤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 is defined as the content of whatever is inside { } curly braces. done被定义为{}花括号内的任何内容。 Comma . 逗号 But a gulp task requires a function to execute. 但是gulp任务需要执行一个函数。 Ok, the function to execute is the execution of get_karma_server which returns the instance of the server and .start() 好的,执行的函数是执行get_karma_server,它返回服务器的实例和.start()

If that doesn't make you vomit I don't know what does. 如果这不会让你呕吐我不知道是什么。

This is why it doesn't work 这就是为什么它不起作用

If you don't execute the function then you don't have an instance of the server ,which means that start is not a function of undefined which means that gulp doesn't get its callback. 如果你没有执行该函数,那么你没有服务器的实例,这意味着start不是undefined的函数,这意味着gulp没有得到它的回调。 Hence all the callback related errors. 因此所有与回调相关的错误。

Step 2 第2步

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

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

Still equivalent, but now it makes a little more sense. 仍然相当,但现在它更有意义。 done is still the callback to gulp. 完成仍然是gulp的回调。

Step 3 第3步

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

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

The same function but this time we just return instead of providing a callback if you are not using it. 相同的功能,但这次我们只返回而不是提供回调,如果你不使用它。

Suggestion 建议

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

Be verbose. 要冗长。 It is not any slower at run-time and it is a heck of a lot faster to understand. 它在运行时并不慢,而且理解起来要快得多。

-------------- Edit -------------- --------------编辑--------------

@Mark, my apologizes. @Mark,我道歉。 I understood the question but did not convey the message. 我理解这个问题,但没有传达信息。 It is not a matter of ES5 vs ES6. 这不是ES5与ES6的关系。

The parenthesis () syntax is used for execution, right?. 括号()语法用于执行,对吗? You can execute something that is not a function but javascript will try to execute it nonetheless giving errors and what not. 你可以执行一些不是函数的东西,但是javascript会尝试执行它,但是会给出错误而不是错误。

In this case you could just provide karma with a function by name, say x, then karma will take x and call () on it by means of x(). 在这种情况下,您可以通过名称提供带有函数的业力,比如x,然后业力将通过x()获取x和call()。 Right? 对? This is because it is expecting x to be a function to call after it is done processing your tests. 这是因为它希望x在处理完测试后成为一个函数。 Hence the call-back. 因此回叫。

Now, within x javascript will execute everything just like a regular function but then it runs into this done thing and it does not know what to do with it because x itself does not take a call back. 现在,在x javascript中将执行所有内容,就像常规函数一样,但它会遇到这个完成的事情,它不知道如何处理它因为x本身不接​​受回调。

In code: 在代码中:

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

Using done within this version of x: 在此版本的x中使用完成:

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

Using done here will work just fine. 在这里使用完成将工作得很好。

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

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

However, we have the first version of x as a callback to karma, which means that we must manually call done: 但是,我们将x的第一个版本作为karma的回调,这意味着我们必须手动调用done:

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

I hope that made more sense. 我希望这更有意义。 I hate it when I'm incoherent and this post has gone longer than it was supposed to. 当我语无伦次时,我讨厌这个帖子已经比预期的要长了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 gulp karma test TypeError:服务器不是函数 - gulp karma test TypeError: Server is not a function 吞咽-完成后发出哔哔声 - gulp - Beep when done 为什么 reverse() 在重新分配数组之前完成时不起作用,但在之后完成时起作用? - Why does reverse() not work when it's done before the array is re-assigned, but works when it's done afterwards? gulp错误-使用gulp.watch时_.flattenDeep不是函数 - gulp error - _.flattenDeep is not a function when using gulp.watch 为什么.done()需要匿名函数? - Why does .done() require an anonymous function? jQuery $ .when()。done()是否等待所有$ .ajax()。done()完成吗? - Does jquery $.when().done() wait for all $.ajax().done()'s to complete? 为什么我的jQuery when()。then()函数在何时完成ajax请求之前触发? - Why does my jQuery when().then() function trigger before the ajax request in when is done? 为什么将 function 参数作为字符串或引用传递时,“this”会发生变化? - Why does `this` change when passing the function argument as string or reference? 在.done之外调用函数时,SignalR不调用服务器中心方法 - SignalR does not invoke server hub method when calling function outside of .done 为什么传递数据对象时第一个$ .ajax错误? - Why does the first $.ajax error when passing a data object?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM