Node 庫以多種方式處理異步功能。最常見的模式是 error-first callbacks,但是你還可能會(huì)遇到 streams、promises、event emitters、child processes, 或 observables。gulp 任務(wù)(task)規(guī)范化了所有這些類型的異步功能。
當(dāng)從任務(wù)(task)中返回 stream、promise、event emitter、child process 或 observable 時(shí),成功或錯(cuò)誤值將通知 gulp 是否繼續(xù)執(zhí)行或結(jié)束。如果任務(wù)(task)出錯(cuò),gulp 將立即結(jié)束執(zhí)行并顯示該錯(cuò)誤。
當(dāng)使用 series() 組合多個(gè)任務(wù)(task)時(shí),任何一個(gè)任務(wù)(task)的錯(cuò)誤將導(dǎo)致整個(gè)任務(wù)組合結(jié)束,并且不會(huì)進(jìn)一步執(zhí)行其他任務(wù)。當(dāng)使用 parallel() 組合多個(gè)任務(wù)(task)時(shí),一個(gè)任務(wù)的錯(cuò)誤將結(jié)束整個(gè)任務(wù)組合的結(jié)束,但是其他并行的任務(wù)(task)可能會(huì)執(zhí)行完,也可能沒有執(zhí)行完。
const { src, dest } = require('gulp');
function streamTask() {
return src('*.js')
.pipe(dest('output'));
}
exports.default = streamTask;
function promiseTask() {
return Promise.resolve('the value is ignored');
}
exports.default = promiseTask;
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;
const { exec } = require('child_process');
function childProcessTask() {
return exec('date');
}
exports.default = childProcessTask;
const { Observable } = require('rxjs');
function observableTask() {
return Observable.of(1, 2, 3);
}
exports.default = observableTask;
如果任務(wù)(task)不返回任何內(nèi)容,則必須使用 callback 來指示任務(wù)已完成。在如下示例中,callback 將作為唯一一個(gè)名為 cb() 的參數(shù)傳遞給你的任務(wù)(task)。
function callbackTask(cb) {
// `cb()` should be called by some async work
cb();
}
exports.default = callbackTask;
如需通過 callback 把任務(wù)(task)中的錯(cuò)誤告知 gulp,請將 Error 作為 callback 的唯一參數(shù)。
function callbackError(cb) {
// `cb()` should be called by some async work
cb(new Error('kaboom'));
}
exports.default = callbackError;
然而,你通常會(huì)將此 callback 函數(shù)傳遞給另一個(gè) API ,而不是自己調(diào)用它。
const fs = require('fs');
function passingCallback(cb) {
fs.access('gulpfile.js', cb);
}
exports.default = passingCallback;
gulp 不再支持同步任務(wù)(Synchronous tasks)了。因?yàn)橥饺蝿?wù)常常會(huì)導(dǎo)致難以調(diào)試的細(xì)微錯(cuò)誤,例如忘記從任務(wù)(task)中返回 stream。
當(dāng)你看到 "Did you forget to signal async completion?" 警告時(shí),說明你并未使用前面提到的返回方式。你需要使用 callback 或返回 stream、promise、event emitter、child process、observable 來解決此問題。
如果不使用前面提供到幾種方式,你還可以將任務(wù)(task)定義為一個(gè) async 函數(shù),它將利用 promise 對你的任務(wù)(task)進(jìn)行包裝。這將允許你使用 await 處理 promise,并使用其他同步代碼。
const fs = require('fs');
async function asyncAwaitTask() {
const { version } = fs.readFileSync('package.json');
console.log(version);
await Promise.resolve('some result');
}
exports.default = asyncAwaitTask;
更多建議: