Gulp 调用函数时出现异步完成错误,或者在默认函数上调用回调时回调不是函数

cdmah0mi  于 2022-12-08  发布在  Gulp
关注(0)|答案(3)|浏览(176)

我正在尝试创建一个调用其他函数的函数:

copy = () => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
}
exports.copy = copy;

使用gulp copy时,函数可以工作,但我得到以下错误:
以下任务未完成:收到,你是不是忘了发出异步完成信号?
我不习惯它,搜索后,我只是改变了我的功能,如下所示,它的工作没有错误:

copy = (done) => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
    done();
}
exports.copy = copy;

然后我将其添加到默认函数中:

defaultFunction = () => {
    copy();
    browsersyncServe();
}
exports.default = defaultFunction;

我的问题是当我用gulp调用默认函数时:
done不是函数
如果我在默认函数中直接调用copyHtmlcopyCsscopyJscopyImg,它就可以工作,不会出现错误。
我错过了什么?

watbbzwu

watbbzwu1#

看起来你的函数是同步运行的,没有返回任何东西。虽然这在gulp的早期版本中是有效的,但是现在它不再支持同步函数了。现在你需要使用回调函数(就像你的问题中那样),或者返回一个流、承诺、事件发射器、子进程或可观察对象(参见https://stackoverflow.com/a/36899424了解一些实现)。
对于你的情况,有一堆事情可以工作,但这里有三种可能性:

使用async函数

因为gulp支持promises,所以你可以把所有的函数都设为async,你可以像调用同步函数一样调用这些函数(因为它们实际上是同步的):

copy = async () => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
}
defaultFunction = async () => {
    // the await isn't strictly necessary, since copy is actually
    // synchronous, but it's probably good practice to use await,
    // if copy ever becomes asynchronous
    await copy(); 
    browsersyncServe();
}
exports.copy = copy;
exports.default = defaultFunction;

回报承诺

同样,对于gulp使用的任何同步函数,都可以返回一个解析的promise(比如Promise.resolve()),就像上面的例子一样,这不会干扰这些函数的同步调用(只要忽略返回值):

copy = () => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
    return Promise.resolve();
}
defaultFunction = () => {
    copy();
    browsersyncServe();
    return Promise.resolve();
}
exports.copy = copy;
exports.default = defaultFunction;

Package 回调函数

另一种可能性是将同步函数 Package 成异步的。例如,使用异步回调格式将看起来像这样:

function wrapSyncToAsync(fn) {
    return function (done) {
        fn();
        done();
    };
}
copy = () => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
}
defaultFunction = () => {
    copy();
    browsersyncServe();
}
exports.copy = wrapSyncToAsync(copy);
exports.default = wrapSyncToAsync(defaultFunction);

这里copy是您的同步版本,您可以通过copy()调用它,而exports.copy是gulp将通过回调调用的内容,例如exports.copy(callbackFunction)
可以使用wrapSyncToAsync将同步函数(没有任何参数)转换为异步函数。

chy5wohz

chy5wohz2#

copy函数的参数中需要一个回调函数,但在defaultFunction中调用它时没有参数,这样就没有定义,这就是为什么它会抱怨“done不是函数”。
看起来你的所有函数都是同步的,done没有用。所以你可以只传递一个伪函数给copy

// the defaultFunction should call the done callback on finish as well
defaultFunction = (done) => {
    copy(() => {});
    browsersyncServe();
    done();
}
exports.default = defaultFunction;

顺便说一句,在gulp任务中一个一个执行动作的更好的方法是使用series来组合函数,每个要组合的函数都需要接受一个回调函数:
第一次

sxpgvts3

sxpgvts33#

当您调用此函数时:

defaultFunction = () => {
    copy();
    browsersyncServe();
}
exports.default = defaultFunction;

您正在调用copy(),但没有任何参数。因此:

copy = (done) => {
    copyHtml();
    copyCss();
    copyJs();
    copyImg();
    done();
}
exports.copy = copy;

done未正确定义。这是错误。
您可以传递done

defaultFunction = (done) => {
    copy(done);
    browsersyncServe();
}
exports.default = defaultFunction;

相关问题