我试图理解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));
。这是有道理的,因为它不是。但它也没有在工作示例中定义。那为什么它在那里工作?
答案 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();
});
};