如何在 Gulp 4 中使用 async/await?

Posted

技术标签:

【中文标题】如何在 Gulp 4 中使用 async/await?【英文标题】:How to use async/await with Gulp 4? 【发布时间】:2016-03-15 06:51:12 【问题描述】:

我正在尝试做这样的事情:

gulp.task("test", async () => 
    return gulp.src("**/*.scss")
        .pipe(print((filePath) => `File: $filePath`));
);

(打印是gulp-print)

但它给出了以下内容:

[22:08:43] Starting 'test'...
[22:08:43] Finished 'test' after 12 ms
[22:08:43] File: src\app\styles\app.scss
[22:08:43] File: src\app\styles\test.scss

即它在打印消息之前完成。

我正在使用 Gulp 4(我认为是 alpha 2)和 TypeScript(1.8.0-dev.20151204)。

生成的 (ES6) 代码如下所示:

gulp.task("test", () => __awaiter(this, void 0, Promise, function* () 
    return gulp.src("**/*.scss")
        .pipe(print((filePath) => `File: $filePath`));
));

__awaiter 在哪里:

var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) 
    return new Promise(function (resolve, reject) 
        generator = generator.call(thisArg, _arguments);
        function cast(value)  return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve)  resolve(value); ); 
        function onfulfill(value)  try  step("next", value);  catch (e)  reject(e);  
        function onreject(value)  try  step("throw", value);  catch (e)  reject(e);  
        function step(verb, value) 
            var result = generator[verb](value);
            result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
        
        step("next", void 0);
    );
;

是否有可能让这个工作?我想在我的任务函数中使用await,但是如果不将该函数标记为异步,我就无法执行此操作。

我可能遗漏了一些明显的东西。

【问题讨论】:

【参考方案1】:

在here 和here 的帮助下,我得以完成这项工作。

gulp.task("test", async () => 
    await new Promise((resolve, reject) => 
        gulp.src("**/*.scss")
            .pipe(print((filePath) => `File: $filePath`))
            .on("end", resolve);
    );
);

在我的实际任务中,我不得不使用finish 事件而不是end 事件(参见上面的第二个链接)。

目前还不清楚这一切是如何运作的,但我认为大致如下:

    Gulp 函数是异步的,因此需要等待它们,但由于它们不是 Promise,因此您必须将它们封装在一个中。 为了解决 promise,您需要监听 endfinish 事件,取决于最后一个管道返回的内容。

另一个似乎有效的选项是resume(),后跟on("end"),在通常需要finish的情况下。这可能是因为this。我不确定哪个选项更好。

我很想进一步了解这一点,所以如果您能够用简单的术语解释这一点,请随时发表评论或发布答案。

编辑:您也可以返回承诺,而不是等待它。

【讨论】:

【参考方案2】:

根据@glen-84 的回答,我找到了我的解决方案,它并没有真正不同,但也不相同。

不知何故,我在直接使用parallel/series 时遇到了一些问题,再次导致did you signal async completion 错误。 可能是由我在代码中监督的错误引起的。

基于undertaker readme中的这个例子:

taker.task('task3', function()
  return new Promise(function(resolve, reject)
    // do things

    resolve(); // when everything is done
  );
);

我使用过这种结构,它似乎对taskseries/parallel 工作正常:

function someTask() 
    return new Promise(async (resolve, reject) => 
        await prepareSomethingAsync()
        gulp.src(somePath)
            .pipe(doingSomething())
            .pipe(await doingSomethingBasedOnAsyncResult())
            .on('finish', resolve)
            .on('error', reject)
    )


// e.g.: gulp.task('Some Name', someTask)

// e.g.: gulp.series(someTask)

// e.g.: gulp.parallel([someTask, someTask])

【讨论】:

以上是关于如何在 Gulp 4 中使用 async/await?的主要内容,如果未能解决你的问题,请参考以下文章

Gulp 4:如何检测复杂构建脚本中的“您是否忘记发出异步完成信号?”错误

我如何在 gulp 4.0 版中重写这个 gulpfile.js

如何使用 gulp 从 node_modules 导入 bootstrap 4 sass/scss

如何解决Gulp 4.0错误?

熟悉Gulp的4个API 让你成为Gulp专家

前端进阶之路-四如何利用gulp创建web前端开发框架(终)