当我将函数抽象为命名函数时,为什么这个回调未定义?

时间:2014-09-16 10:31:58

标签: javascript gulp

我试图理解javascript回调的概念,并且正在改变使用回调的这段(工作)代码:

/* Working */

var gulp = require('gulp'),
    del  = require('del');

var cfg  = require(process.cwd() + '/config.json');

gulp.task('del:dist', function(cb) {
  del([cfg.path.dist], function(err) {
    if (err) return cb(err);
    cb();
  });
});

使用命名函数的代码,以便我可以更好地理解正在发生的事情:

/* Not working */

var gulp = require('gulp'),
    del  = require('del');

var cfg  = require(process.cwd() + '/config.json');

gulp.task('del:dist', deleteFolder(cfg.path.dist, cb));

function deleteFolder(targetFolder, cb) {
  del(targetFolder, function doneDeleting(err) {
    if (err) return cb(err);
    cb();
  });
};

问题是具有命名函数的代码不起作用。我为referenceError: cb is not defined获得deleteFolder(cfg.path.dist, cb));。这是有道理的,因为它不是。但它也没有在工作示例中定义。那为什么它在那里工作?

3 个答案:

答案 0 :(得分:1)

当你这样做时

gulp.task('del:dist', deleteFolder(cfg.path.dist, cb));

您没有通过gulp.task回调。您正在调用函数deleteFolder并传递它的返回值。由于它什么都不返回,因此该函数的返回值为undefined。因此,您会看到错误。

答案 1 :(得分:1)

回调通常将函数引用或匿名函数作为其参数。执行回调的函数确定给予此函数的参数。

可以使用函数名称引用函数,而不使用参数,例如deleteFolder。如果添加括号,那么当最初运行该代码时,将对其进行评估,并将该函数的返回值传递给task函数,而不是传递函数本身。

如果你只是在没有括号的情况下传递它deleteFolder,它会回调你的函数传入targetFolder作为唯一的参数(cb在你的函数中将为null)。 'targetFolder'变量将包含您希望在cb中找到的内容。

task函数传递给任何回调函数的唯一值是一个参数(此处标记为cb)。

此外,您无法在参数内定义诸如“doneDeleting”之类的函数。您需要单独定义并通过引用传递它(如上所述)。但是,当您从其中调用cb()时(仅在回调被触发时才传入),您需要将doneDeleting函数作为匿名函数传递,而不是将其命名为通过引用传递它,因为cb不在您的函数定义的范围内。

在您的情况下,以下内容将起作用:

var gulp = require('gulp'),
    del  = require('del');

var cfg  = require(process.cwd() + '/config.json');

gulp.task('del:dist', deleteFolder);

function deleteFolder(cb) {
  del([cfg.path.dist], function(err) {
    if (err) return cb(err);
    cb();
  });
};

我总是想知道你应该怎么知道回调函数会传递多少个参数。答案纯粹是文档,或者是失败,试验和错误/拖网代码。基本上,回调函数的参数不是由你决定的!

这样想。通常,在函数运行了一些由该函数生成的新数据之后,回调的作用就是做某事。函数完成后,我们想要对该数据执行某些操作。我们获取数据的方式是通过传递创建数据的函数,将其传递给我们的参数,然后我们可以操作它。如果我们传入自己的参数,那么我们可能永远无法访问函数生成的数据。

最好看一下回调函数的含义是否合适 - here是一个很好的起点(它在AJAX请求结束时使用回调)。

答案 2 :(得分:-1)

gulp.task的回调函数只接受一个参数。因此,您使用的命名函数只有一个参数。

正确版本如下,

var gulp = require('gulp'),
del  = require('del');
var cfg  = require(process.cwd() + '/config.json');

gulp.task('del:dist', deleteFolder);

function deleteFolder(cb) {
  del([cfg.path.dist], function doneDeleting(err) {
    if (err) return cb(err);
    cb();
  });
};