首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“回调已被调用”的Async.js

“回调已被调用”的Async.js
EN

Stack Overflow用户
提问于 2015-10-28 22:15:28
回答 3查看 543关注 0票数 0

我使用async.js以一些有序的顺序加载我的吞咽任务,所以我这样做:

代码语言:javascript
复制
// Gulp Default Build Task
gulp.task('default', function() {
    var tasks = ['sass_dev', 'browserify', 'lint', 'watch'];
    var sync = tasks.map(function(task) {
        return function(callback) {
            gulp.start(task, function(err) {
                if (err || task.length === 0) {
                    callback(err);
                } else {
                    callback(null, task[0]);
                }
            });
        };
    });
    async.series(sync);
});

任务运行正常,但在脚本第一次更改之后,我有一个错误,即if (fn === null) throw new Error("Callback was already called.");。我知道这是bc,它会调用两次回调,但是即使在err条件下,它也不能工作。有人能帮忙吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-29 16:35:58

问题

您遇到这个问题的原因是,您使用的是Gulp的一部分,而该部分实际上并不适合最终的Gulp用户使用。下面是一个可以复制您所报告的行为的小吞咽文件:

代码语言:javascript
复制
var gulp = require("gulp");

gulp.task('foo');

gulp.task('default', function () {
    gulp.start('foo', function () {
        console.log("callback!");
    });
    setTimeout(function () {
        gulp.start('foo');
    }, 1000);
});

运行此操作将在控制台上生成:

代码语言:javascript
复制
[12:23:48] Using gulpfile /tmp/t15/test.js
[12:23:48] Starting 'default'...
[12:23:48] Starting 'foo'...
[12:23:48] Finished 'foo' after 66 μs
[12:23:48] Finished 'default' after 1.24 ms
callback!
[12:23:49] Starting 'foo'...
[12:23:49] Finished 'foo' after 8.99 μs
callback!

您可以看到,callback!出现了两次,尽管gulp.start只被调用了一次,只有一个回调!问题是,即使在第二次调用gulp.start时,Gulp也会记住回调并使用它。

如果您想要血淋淋的细节,请看策划人,这是Gulp所使用的。查找doneCallback及其管理方式。基本的行为是,如果使用回调调用start,那么它会删除以前的任何doneCallback值,但如果不使用回调调用,则旧值保持不变,并有效地被后续对start的调用重用。

安全的解决办法

不管怎么说。您似乎希望按顺序运行一组任务。我过去这样做的方式是声明将按顺序运行其他任务的任务,以便:

  1. 它的依赖项是要按顺序运行的任务的所有依赖项的联合。
  2. 它的实现函数调用它应该按顺序运行的所有任务的实现函数。

下面是一个简单的例子:

代码语言:javascript
复制
var gulp = require("gulp");

gulp.task('x');
gulp.task('y');
gulp.task('q');

// We are defining task `a`, with dependencies `x` and `y`.
var a_deps = ['x', 'y'];
function a() {
    console.log("a");
}
gulp.task('a', a_deps);

// We are defining task `b`, with dependencies `x` and `q`.
var b_deps = ['x', 'q'];
function b() {
    console.log("b");
}
gulp.task('b', b_deps);

// We are defining task `default`, which is equivalent to running tasks
// `a` and `b` in sequence.
gulp.task('default', a_deps.concat(b_deps), function () {
    a();
    b();
});

为了记录在案,我不使用run-sequence,因为当我尝试它时,我看到它多次运行我的依赖项,这是我无法接受的。

当Gulp 4发布时,我们将能够使用gulp.series对任务进行排序

票数 1
EN

Stack Overflow用户

发布于 2015-10-29 02:08:23

有一个更简单的方法。

代码语言:javascript
复制
'use strict';

let gulp = require('gulp');
let concat = require('gulp-concat');
let minifyCSS = require('gulp-minify-css');
let browserify = require('browserify');
let vsource = require("vinyl-source-stream");
let babel = require('babelify');

let source = {
	appjs: './ui-src/app.js',
	js: ['./ui-src/**/*.js'],
	libjs: ['./ui-src/lib/primus/primus.js'],
	appcss: ['./ui-src/css/*.css'],
	apphtml: ['./ui-src/**/*.html'],
	appimg: ['./ui-src/img/*']
};

gulp.task('appjs', function(){
	browserify({ debug: true })
		.transform(babel.configure({stage: 0}))
		.require(source.appjs, { entry: true })
		.bundle()
		.pipe(vsource('app.min.js'))
		.pipe(gulp.dest('./ui-dist'));
});

gulp.task('libjs', function () {
	gulp.src(source.libjs)
		.pipe(concat('lib.min.js'))
		.pipe(gulp.dest('./ui-dist'))
});

gulp.task('appcss', function () {
	gulp.src(source.appcss)
		.pipe(concat('app.min.css'))
		.pipe(minifyCSS())
		.pipe(gulp.dest('./ui-dist'))
});

gulp.task('apphtml', function() {
	gulp.src(source.apphtml)
		.pipe(gulp.dest('./ui-dist'));
	gulp.src(source.appimg, {base: 'ui-src'})
		.pipe(gulp.dest('./ui-dist'));
});

gulp.task('watch', function() {
	gulp.watch(source.appcss, ['appcss']);
	gulp.watch(source.apphtml, ['apphtml']);
	gulp.watch(source.js, ['appjs']);
});

gulp.task('default', ['appjs', 'appcss', 'apphtml', 'watch']);

gulp.task('nw', ['appjs', 'libjs', 'appcss', 'apphtml']);

票数 0
EN

Stack Overflow用户

发布于 2015-10-30 00:36:04

我使用了其他更轻的叫做run-sequence的库,它的工作非常流畅。因此,这是一个示例解决方案:

代码语言:javascript
复制
var sequence    = require('run-sequence');

gulp.task('default', function(callback) {
    sequence('sass_dev', ['browserify', 'lint'], 'watch', callback);
});
gulp.task('prod', function(callback) {
    sequence('sass_dev', ['browserify'], 'uglify', callback);
});

npm链路

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33402544

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档