简体   繁体   English

在JavaScript函数中使用done作为参数是什么意思?

[英]What is the meaning of using done as a parameter in a javascript function?

i am learning Javascript, and it seems that the done as a parameter in a function is a difficult concept to understand. 我正在学习Javascript,并且似乎把函数作为参数完成是一个很难理解的概念。 I want to know why it does behaves like that (done as a parameter (completed process signal i guess), and if there is some good book or resource Online to study further this concept. Example , i am following along with a Tutorial and it uses done as a parameter, the thing is that when i run the code on node via gulp (gulpfile.js) the process never stops when using done, if i choose to skip done in the code it runs smoothly. I am trying to track down the problem, and i know that the problem is the done as a parameter, ( it has been checked by me multiple times). 我想知道为什么它的行为如此(作为参数完成(我想是完成的过程信号),并且是否有一些不错的书或在线资源可以进一步研究这个概念。 例如 ,我将跟随一个教程及其使用done作为参数,问题是当我通过gulp(gulpfile.js)在节点上运行代码时,使用done时该过程永远不会停止,如果我选择跳过代码中的done则它运行平稳。解决问题,我知道问题是作为参数完成的(我已经对其进行了多次检查)。

gulp.task('clean-styles', function(done) {
    var files = config.temp + '**/*.css';
    clean(files, done);
});


function clean(path, done) {
    log('Cleaning: ' + $.util.colors.blue(path));
    del(path, done).then(function(path) {
        console.log("path=",util.inspect(path,false,null))
        console.log('Deleted Files\/Folders:\n', path.join('\n'));
        console.log('Finishing clean')
    });
}
  • node version: 0.12.4 节点版本:0.12.4
  • npm version: 2.10.1 npm版本:2.10.1
  • gulp version: 3.9.0 gulp版本:3.9.0

Thanks a lot for any help, it will be really appreciated. 非常感谢您的帮助,我们将不胜感激。 Salutations. 称呼。

can only explain the concept. 只能解释这个概念。 what you are trying to achieve is not clear enough. 您试图达到的目标还不够清楚。

done is just a non-official standard name for a function (aka callback) that informs the calling function (parent in stacktrace) that a task is completed. done只是一个函数(也称为回调)的非官方标准名称,它通知调用函数(stacktrace中的父代)任务已完成。

recall that javascript is asynchronous and functions can be passed around as variables. 回想一下,javascript是异步的,并且函数可以作为变量传递。

now, imagine a function startPrinting that has to call printText1 , printText2 and printText3 and then output message that process is completed. 现在,想象一个函数startPrinting ,它必须调用printText1printText2printText3 ,然后输出该过程已完成的消息。 We have: 我们有:

function startPrinting() {
    printText1();
    printText2();
    printText3();
    console.log("completed");
}
function printText1() {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=3uPCavLN', function(response){
        console.log(response)
    });
}
function printText2() {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=jZjqKgNN', function(response){
        console.log(response)
    });
}
function printText3() {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=SreCbunb', function(response){
        console.log(response)
    });
}

here, there is no assurance that completed will ALWAYS be printed after all three functions have been executed. 在此,不能保证在执行completed所有三个功能后始终会打印completed since they execute asynchronously. 因为它们异步执行。

in order to sort this, javascript ninjas will introduce a done function so that startPrinting will only print completed when all three functions have been executed. 为了对此进行排序,javascript忍者将引入完成函数,以便startPrinting仅在所有三个函数均已执行时才打印completed Notice how a function is passed to printText1 ... 2 below: 请注意如何将函数传递给下面的printText1 ... 2

function startPrinting() {
    /* START OF DONE ROUTINE */
    var count = 0;
    var printCompleted = function() {
        count+=1;

        if(count == 3)
            console.log("completed");
    }
    /* END */
    printText1(printCompleted);
    printText2(printCompleted);
    printText3(printCompleted);
}
function printText1(done) {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=3uPCavLN', function(response){
        console.log(response)
        done();
    });
}
function printText2(done) {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=jZjqKgNN', function(response){
        console.log(response)
        done();
    });
}
function printText3(done) {
    $.get('http://ps-web.cloudapp.net/proxy.php?url=http://pastebin.com/raw.php?i=SreCbunb', function(response){
        console.log(response)
        done();
    });
}

I hope you are able to apply this principle to better understanding your context. 我希望您能够应用此原理来更好地了解您的上下文。

Functions are first class objects in JavaScript. 函数是JavaScript中的一流对象。 You can pass them around like any other value. 您可以像传递其他任何值一样传递它们。 Once they have been passed to another function as an argument, then you can call them using the argument name (or call another function and pass them as an argument to that, or assign them properties, or convert them to strings, or whatever else you'd like to do with them). 一旦将它们作为参数传递给另一个函数,则可以使用参数名称来调用它们(或调用另一个函数并将其作为参数传递给该函数,或者分配它们的属性,或者将它们转换为字符串,或者其他方式想和他们一起做)。

 function this_sets_the_body() { document.body.innerHTML = "Hello, world"; } function this_calls_a_callback(im_a_callback) { im_a_callback(); } this_calls_a_callback(this_sets_the_body); 

In your code, you've written a function using an anonymous function expression: 在代码中,您已经使用匿名函数表达式编写了一个函数:

 function(done) { // ... } 

… and you've told it to expect to be called with an argument which you are calling done . …并且您已经告诉它期望以您称为done的参数来调用它。

Whatever value is passed to it, you are ignoring (your function doesn't mention done after the argument name). 无论将什么值传递给它,您都将忽略(您的函数在参数名称后没有提及done )。

The library you are using (presumably) is passing a function in there and expects you to call it once your function as done whatever it is that it is going to do. 您正在使用的库(大概)正在其中传递一个函数,并且希望您在函数完成后立即调用它。 This lets it wait until anything asynchronous that you are doing is finished. 这样一来,它就可以等到您正在执行的所有异步操作完成为止。

So call done() when your code is done. 因此,在代码完成后调用done()

It looks like your example is fully messed up with respect to callbacks. 看来您的示例在回调方面完全搞砸了。 In some places in your example done is used as a callback -- a function given from outside to be called when everything is finished in an asynchronous process and signal the end of the operation. 在您的示例中的某些地方, done被用作回调-从外部给定的函数,当异步过程中的所有操作完成并发出操作结束信号时,将调用该函数。 In other cases it looks to be used as an argument provided by the execution method itself. 在其他情况下,它似乎用作执行方法本身提供的参数。 In yet another you use it in a promise . 在另一种情况下,您可以在promise使用它。 Anyway, as I am not familiar with gulp I can only guess, but I hope the following example would work for you to explain the concepts of callback and partially promise . 无论如何,由于我对 gulp 并不熟悉,所以我只能猜测,但是我希望以下示例可以为您解释callback和部分promise的概念。 I would, however, recommend to avoid situations of missing callbacks and promises in the same code as it leads to confusion. 但是,我建议避免在同一代码中丢失回调和Promise的情况,因为这会导致混乱。

gulp.task('clean-styles', function(done) {
   console.log(1);
   /* we are in the callback of gulp.task: we give the
    * latter this anonymous function to call when the 
    * setup is ready and it gives us function done to
    * call when we are done and signal the engine any errors
    */
   var files = config.temp + '**/*.css';

   /* this defines the action to take when files are actually deleted */
   var callback = function(err, message) {
       console.log(6);
       console.log(message); // expect: looks good
       // this is provided apparently by gulp and calling it signals the engine that everything is completed
       done(err);
   };

   /* we call this function, but some bits (like deletion 
    * run asynchronously. The function will return quickly, but
    * callback (function) will only be called when files are deleted */
   clean(files, callback);
   /* the execution of gulp.task callback is finished,
    * but files are not yet deleted */
   console.log(4);
});

/* done here is not the same done as above, it is actually
 * the function we supply into the call above, i.e. `callback` */
function clean(path, done) {
    /* the cleanup is starting */
    console.log(2);
    /* del is scheduled. it returns a `promise` and if
     * we call `then`, then the given anonymous function
     * will be executed when files are deleted. This is
     * where we call the provided function `done` to
     * signal that the job is complete and execute some action */
    del(path).then(function() {
        /* files are deleted and this callback is called */
        console.log(5);
        /* we let the outer caller know by calling `done` which
         * was given to us from outside */
        done(null, "looks good"); // null means no error
    }).catch(function(err) {
        done(err, "looks bad"); // err is given back
    });
    /* the clean method is through, but files not yet deleted */
    console.log(3);
}

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM