撰寫產生器時,最重要的概念之一是如何執行方法,以及在哪個背景中執行方法。
原型方法作為動作
每一個直接附加到產生器原型的原型都被視為一個工作。每一個工作都由 Yeoman 環境執行迴圈依序執行。
換句話說,由 Object.getPrototypeOf(Generator)
傳回的物件上每個函式都會自動執行。
輔助方法和私有方法
現在您知道原型方法被視為一個工作了,您可能會好奇如何定義不會自動呼叫的輔助或私有方法。有以下三種方法可以實現這個目的。
方法名稱前綴為底線(例如
_private_method
)。class extends Generator { method1() { console.log('hey 1'); } _private_method() { console.log('private hey'); } }
使用實體方法
class extends Generator { constructor(args, opts) { // Calling the super constructor is important so our generator is correctly set up super(args, opts) this.helperMethod = function () { console.log('won\'t be called automatically'); }; } }
延伸父產生器
class MyBase extends Generator { helper() { console.log('methods on the parent generator won\'t be called automatically'); } } module.exports = class extends MyBase { exec() { this.helper(); } };
執行迴圈
如果只有一個產生器,則按順序執行工作是可以的。但是當您開始組合產生器時,這是不夠的。
這就是 Yeoman 使用**執行迴圈**的原因。
執行迴圈是一個具有優先順序支援的佇列系統。我們使用 Grouped-queue 模組來處理執行迴圈。
優先順序在您的程式碼中定義為特殊的原型方法名稱。當方法名稱與優先順序名稱相同時,執行迴圈會將方法推入此特殊佇列。如果方法名稱與優先順序不符,則會推入 default
群組。
在程式碼中,它會看起來像這樣
class extends Generator {
priorityName() {}
}
您也可以使用雜湊而不是單一方法,將多個方法分組到佇列中一起執行
Generator.extend({
priorityName: {
method() {},
method2() {}
}
});
(請注意,最後這個技巧不適用於 JS class
定義)
可用的優先順序為(按執行順序)
initializing
-您的初始化方法(檢查目前的專案狀態、取得組態等)prompting
-您提示使用者輸入選項的地方(您會在這裡呼叫this.prompt()
)configuring
-儲存組態並組態專案(建立.editorconfig
檔案和其他元資料檔案)default
-如果方法名稱與優先順序不符,則會推入到此群組。writing
-您寫入產生器特定檔案的地方(路由、控制器等)conflicts
-處理衝突的地方(內部使用)install
-執行安裝的地方(npm、bower)end
-最後呼叫,清理,說再見等
遵循這些優先順序準則,您的產生器就會與其他產生器順利相容。
非同步工作
有許多方法可以暫停執行迴圈,直到工作非同步執行完畢。
最簡單的方法是**傳回 Promise。**當 Promise 解決後,迴圈會繼續執行,或者如果 Promise 失敗,迴圈會引發例外並停止。
如果您依賴的非同步 API 不支援 Promise,則您可以依賴傳統的 this.async()
方式。呼叫 this.async()
會傳回一個函式,在工作完成後呼叫此函式。例如
asyncTask() {
var done = this.async();
getUserEmail(function (err, name) {
done(err);
});
}
如果 done
函式被帶有錯誤參數呼叫,執行迴圈將會停止,並且例外將會被提出。
接下來該怎麼辦?
現在你對於 Yeoman 執行區塊了解得更多了,你可以繼續閱讀 使用者互動。