【问题标题】:Why might I be getting "task completion callback called too many times" in gulp?为什么我会在 gulp 中收到“任务完成回调调用太多次”?
【发布时间】:2015-05-13 19:17:41
【问题描述】:

鉴于以下 gulp 任务,为什么我会收到以下错误?

错误:任务完成回调调用次数过多

function myTask(options, cb) { // cb is the gulp cb
  var serverInstance = http.createServer(dispatch({ /*routes*/ }));

  serverInstance.listen(options.port, function() {
    cb(); // Stack trace identifies this line as throwing the error
  });
}

function partial(fn) {   
    var args = Array.prototype.slice.call(arguments, 1);

    return function() {
        return fn.apply(this, args.concat(Array.prototype.slice.call(arguments)));
    };
}

gulp.task('task-name', ['task-dependency'], partial(myTask, { port: 8080 }));

编辑:

以下修改使其工作(但我的问题仍然存在):

gulp.task('task-name', ['task-dependency'], function(cb) {
  partial(myTask, { port: 8080 })(cb);
});

【问题讨论】:

  • 我对 gulp 不是很熟悉,但它不是用来构建的吗?您似乎正在使用它来启动服务器。如果您多次访问该服务器,cb() 回调将被多次调用。
  • 是的,在此构建任务结束时,将启动一个服务器,该服务器将交付应用程序以在开发人员的机器上进行测试。
  • @JLRishe 提供的回调仅在服务器(IIUC)引发监听事件时调用一次nodejs.org/api/…
  • 这个问题是否与需要向 gulp 提供有关任务终止方式的提示有关?
  • @JLRishe 不符合 http-server 文档。当服务器开始监听时,该回调应该只被调用一次。

标签: javascript gulp


【解决方案1】:

这是因为 gulp 使用启发式(包括回调的返回值以及是否接受回调参数)来检测异步与同步任务,并相应地对待它们。我的部分函数返回一个没有声明参数的函数,这让 gulp 在异步时认为它是同步的。

修改 partial 以返回具有单个命名参数的函数解决了该问题。

//...
return function(cb) {
  return fn.apply(this, args.concat(slice.call(arguments)));
};
//...

【讨论】:

  • 如果您在部分函数应用程序中使用.bind(),它将创建一个具有正确数量的函数:(function myTask(options, cb){}).bind(null, { port: 8080 }).length === 1
  • 好点。我最初避免绑定是因为我不想影响函数的接收者。另外,是否有一种机制可以在运行时更改函数的数量而不使用绑定(或评估)?例如,length 是否可写?编辑:没有length 不可写
  • AFAIK,唯一的其他选择是使用函数构造函数,但这很hacky。该语法并没有真正提供任何干净的选项来动态指示创建的函数具有的参数数量。 lodash 的 _.bind_.curry_.partial 的所有返回函数的数量为 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 2015-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-26
  • 1970-01-01
相关资源
最近更新 更多