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

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

本文关键字:参数 是什么 意思 done 函数 javascript      更新时间:2023-09-26

我正在学习Javascript,似乎在函数中作为参数的done是一个难以理解的概念。我想知道为什么它的行为是这样的(作为一个参数(我猜是完成的过程信号),如果有一些好的书籍或在线资源来进一步研究这个概念。示例,我跟随教程,它使用完成作为参数,问题是,当我通过gulp (gulpfile.js)在节点上运行代码时,如果我选择在代码中跳过完成,它会顺利运行。我正在试图追踪问题,我知道问题是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')
    });
}
  • 节点版本:0.12.4
  • npm version: 2.10.1
  • gulp版本:3.9.0

非常感谢的任何帮助,这将是非常感激的。你好。

只能说明概念。你想达到的目标不够明确。

done只是一个函数(又名回调)的非官方标准名称,它通知调用函数(stacktrace中的父函数)任务已经完成。

还记得吗,javascript是异步的,函数可以作为变量传递。

现在,想象一个函数startPrinting,它必须调用printText1, printText2printText3,然后输出进程完成的消息。我们有:

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)
    });
}
这里的

不能保证completed在执行完所有三个函数后会打印ALWAYS。因为它们是异步执行的

为了排序,javascript忍者将引入一个done函数,这样startPrinting只会在所有三个函数都被执行时打印completed。请注意下面是如何将函数传递给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();
    });
}

我希望你能够运用这个原则来更好地理解你的上下文。

函数是JavaScript中的第一类对象。你可以像传递其他值一样传递它们。一旦它们作为参数传递给另一个函数,那么你就可以使用参数名调用它们(或者调用另一个函数并将它们作为参数传递给该函数,或者为它们分配属性,或者将它们转换为字符串,或者任何你想对它们做的事情)。

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

在您的代码中,您使用匿名函数表达式编写了一个函数:
function(done) {
    // ...
}

…你已经告诉它期待被调用的参数是你正在调用的done

无论传递给它的值是什么,您都忽略了(您的函数在参数名称后没有提到done)。

你正在使用的库(大概)在那里传递一个函数,并期望你在函数完成它将要做的任何事情后调用它。这允许它等待,直到您正在执行的任何异步操作完成。

所以当你的代码完成时调用done()

看起来你的例子在回调方面完全搞砸了。在示例中的某些地方,done被用作回调函数——一个从外部给定的函数,在异步进程中完成所有操作时调用,并发出操作结束的信号。在其他情况下,它似乎被用作执行方法本身提供的参数。在另一个promise中使用它。无论如何,由于我对 gulp不熟悉,我只能猜测,但我希望下面的例子可以帮助您解释callback和部分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);
}