- 异步执行任务(task)完成通知返回 stream返回 promise返回 event emitter返回 child process返回 observable使用 callbackgulp 不再支持同步任务(Synchronous tasks)使用 async/await
异步执行
Node 库以多种方式处理异步功能。最常见的模式是 error-first callbacks,但是你还可能会遇到 streams、promises、event emitters、child processes, 或 observables。gulp 任务(task)规范化了所有这些类型的异步功能。
任务(task)完成通知
当从任务(task)中返回 stream、promise、event emitter、child process 或 observable 时,成功或错误值将通知 gulp 是否继续执行或结束。如果任务(task)出错,gulp 将立即结束执行并显示该错误。
当使用 series() 组合多个任务(task)时,任何一个任务(task)的错误将导致整个任务组合结束,并且不会进一步执行其他任务。当使用 parallel() 组合多个任务(task)时,一个任务的错误将结束整个任务组合的结束,但是其他并行的任务(task)可能会执行完,也可能没有执行完。
返回 stream
const { src, dest } = require('gulp');function streamTask() { return src('*.js') .pipe(dest('output'));}exports.default = streamTask;
返回 promise
function promiseTask() { return Promise.resolve('the value is ignored');}exports.default = promiseTask;
返回 event emitter
const { EventEmitter } = require('events');function eventEmitterTask() { const emitter = new EventEmitter(); // Emit has to happen async otherwise gulp isn't listening yet setTimeout(() => emitter.emit('finish'), 250); return emitter;}exports.default = eventEmitterTask;
返回 child process
const { exec } = require('child_process');function childProcessTask() { return exec('date');}exports.default = childProcessTask;
返回 observable
const { Observable } = require('rxjs');function observableTask() { return Observable.of(1, 2, 3);}exports.default = observableTask;
使用 callback
如果任务(task)不返回任何内容,则必须使用 callback 来指示任务已完成。在如下示例中,callback 将作为唯一一个名为 cb() 的参数传递给你的任务(task)。
function callbackTask(cb) { // `cb()` should be called by some async work cb();}exports.default = callbackTask;
如需通过 callback 把任务(task)中的错误告知 gulp,请将 Error 作为 callback 的唯一参数。
function callbackError(cb) { // `cb()` should be called by some async work cb(new Error('kaboom'));}exports.default = callbackError;
然而,你通常会将此 callback 函数传递给另一个 API ,而不是自己调用它。
const fs = require('fs');function passingCallback(cb) { fs.access('gulpfile.js', cb);}exports.default = passingCallback;
gulp 不再支持同步任务(Synchronous tasks)
gulp 不再支持同步任务(Synchronous tasks)了。因为同步任务常常会导致难以调试的细微错误,例如忘记从任务(task)中返回 stream。
当你看到 “Did you forget to signal async completion?” 警告时,说明你并未使用前面提到的返回方式。你需要使用 callback 或返回 stream、promise、event emitter、child process、observable 来解决此问题。
使用 async/await
如果不使用前面提供到几种方式,你还可以将任务(task)定义为一个 async 函数,它将利用 promise 对你的任务(task)进行包装。这将允许你使用 await 处理 promise,并使用其他同步代码。
const fs = require('fs');async function asyncAwaitTask() { const { version } = JSON.parse(fs.readFileSync('package.json', 'utf8')); console.log(version); await Promise.resolve('some result');}exports.default = asyncAwaitTask;
