摘要:本文重點是講解如何解決循環(huán)依賴這個問題。如何找到循環(huán)依賴的的文件上文的示例代碼很簡單,個文件,很容易找出循環(huán)依賴。如果有十幾個文件,手工去找循環(huán)依賴的文件,也是非常麻煩的。
本文重點是講解如何解決循環(huán)依賴這個問題。關(guān)心這個問題是如何產(chǎn)生的,可以自行谷歌。
如何重現(xiàn)這個問題// a.js const {sayB} = require("./b.js") sayB() function sayA () { console.log("say A") } module.exports = { sayA }
// b.js const {sayA} = require("./a.js") sayA() function sayB () { console.log("say B") } module.exports = { sayB }
執(zhí)行下面的代碼
? test git:(master) ? node a.js /Users/dd/wj-gitlab/tools/test/b.js:3 sayA() ^ TypeError: sayA is not a function at Object.(/Users/dd/wj-gitlab/tools/test/b.js:3:1) at Module._compile (module.js:635:30) at Object.Module._extensions..js (module.js:646:10) at Module.load (module.js:554:32) at tryModuleLoad (module.js:497:12) at Function.Module._load (module.js:489:3) at Module.require (module.js:579:17) at require (internal/module.js:11:18) at Object. (/Users/dd/wj-gitlab/tools/test/a.js:1:78) at Module._compile (module.js:635:30)
sayA is not a function那么sayA是個什么呢,實際上它是 undefined
遇到這種問題時,你最好能意識到可能是循環(huán)依賴的問題,否則找問題可能事倍功半。
如何找到循環(huán)依賴的的文件上文的示例代碼很簡單,2個文件,很容易找出循環(huán)依賴。如果有十幾個文件,手工去找循環(huán)依賴的文件,也是非常麻煩的。
下面推薦一個工具 madge, 它可以可視化的查看文件之間的依賴關(guān)系。
注意下圖1,以cli.js為起點,所有的箭頭都是向右展開的,這說明沒有循環(huán)依賴。如果有箭頭出現(xiàn)向左逆流,那么就可能是循環(huán)依賴的點。
圖2中,出現(xiàn)向左的箭頭,說明出現(xiàn)了循環(huán)依賴,說明要此處斷開循環(huán)。
【圖1】
【圖2】
將module.exports放到文件頭部,先將自身模塊導出,然后再導入其他模塊。
來自:http://maples7.com/2016/08/17...
// a.js module.exports = { sayA } const {sayB} = require("./b.js") sayB() function sayA () { console.log("say A") }
// b.js module.exports = { sayB } const {sayA} = require("./a.js") console.log(typeof sayA) sayA() function sayB () { console.log("say A") }方案2: 間接調(diào)用
通過引入一個event的消息傳遞,讓多個個模塊可以間接傳遞消息,多個模塊之間也可以通過發(fā)消息相互調(diào)用。
// a.js require("./b.js") const bus = require("./bus.js") bus.on("sayA", sayA) setTimeout(() => { bus.emit("sayB") }, 0) function sayA () { console.log("say A") } module.exports = { sayA }
// b.js const bus = require("./bus.js") bus.on("sayB", sayB) setTimeout(() => { bus.emit("sayA") }, 0) function sayB () { console.log("say B") } module.exports = { sayB }
// bus.js const EventEmitter = require("events") class MyEmitter extends EventEmitter {} module.exports = new MyEmitter()總結(jié)
出現(xiàn)循環(huán)依賴,往往是代碼的結(jié)構(gòu)出現(xiàn)了問題。應(yīng)當主動去避免循環(huán)依賴這種問題,但是遇到這種問題,無法避免時,也要意識到是循環(huán)依賴導致的問題,并找方案解決。
最后給出一個有意思的問題,下面的代碼運行node a.js會輸出什么?為什么會這樣?
// a.js var moduleB = require("./b.js") setInterval(() => { console.log("setInterval A") }, 500) setTimeout(() => { console.log("setTimeout moduleA") moduleB.sayB() }, 2000) function sayA () { console.log("say A") } module.exports = { sayA }
// b.js var moduleA = require("./a.js") setInterval(() => { console.log("setInterval B") }, 500) setTimeout(() => { console.log("setTimeout moduleB") moduleA.sayA() }, 2000) function sayB () { console.log("say B") } module.exports = { sayB }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/98719.html
摘要:前言最近參加了幾場面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題主要考察前端技基礎(chǔ)是否扎實,是否能夠?qū)⑶岸酥R體系串聯(lián)。 前言 最近參加了幾場面試,積累了一些高頻面試題,我把面試題分為兩類,一種是基礎(chǔ)試題: 主要考察前端技基礎(chǔ)是否扎實,是否能夠?qū)⑶岸酥R體系串聯(lián)。一種是開放式問題: 考察業(yè)務(wù)積累,是否有自己的思考,思考問題的方式,這類問題沒有標準答案。 基礎(chǔ)題 題目的答...
摘要:回調(diào)函數(shù)是在異步操作完成后傳播其操作結(jié)果的函數(shù),總是用來替代同步操作的返回指令。下面的圖片顯示了中事件循環(huán)過程當異步操作完成時,執(zhí)行權(quán)就會交給這個異步操作開始的地方,即回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Enc...
摘要:問題什么是調(diào)用棧并且它是的一部分么調(diào)用棧當然是的一部分。為什么理解是重要的因為你在每個進程中只能獲取一個調(diào)用棧。它是一個從事件隊列中跳去事件的循環(huán)并且將它們的回調(diào)壓入到調(diào)用棧中。當調(diào)用棧為空的時候,事件循環(huán)可以決定下一步執(zhí)行哪一個。 你并不知道Node 原文:You don’t know Node 譯者:neal1991 welcome to star my articles-tra...
摘要:深入淺出一直想致力于寫一篇關(guān)于廣義講解系統(tǒng)的文章,苦于時間有限,資源有限。事件驅(qū)動機制是通過內(nèi)部單線程高效率地維護事件循環(huán)隊列來實現(xiàn)的,沒有多線程的資源占用和上下文的切換。 深入淺出Node.js 一直想致力于寫一篇關(guān)于廣義講解Node.js系統(tǒng)的文章,苦于時間有限,資源有限。這篇文章是在結(jié)合自己的學習心得以及與行業(yè)大佬共同探討下爭對于熟練掌握JS語言后的廣義Node.js.至于為什么...
摘要:深入淺出一直想致力于寫一篇關(guān)于廣義講解系統(tǒng)的文章,苦于時間有限,資源有限。事件驅(qū)動機制是通過內(nèi)部單線程高效率地維護事件循環(huán)隊列來實現(xiàn)的,沒有多線程的資源占用和上下文的切換。 深入淺出Node.js 一直想致力于寫一篇關(guān)于廣義講解Node.js系統(tǒng)的文章,苦于時間有限,資源有限。這篇文章是在結(jié)合自己的學習心得以及與行業(yè)大佬共同探討下爭對于熟練掌握JS語言后的廣義Node.js.至于為什么...
閱讀 1840·2021-09-22 15:23
閱讀 3269·2021-09-04 16:45
閱讀 1874·2021-07-29 14:49
閱讀 2773·2019-08-30 15:44
閱讀 1524·2019-08-29 16:36
閱讀 1044·2019-08-29 11:03
閱讀 1511·2019-08-26 13:53
閱讀 510·2019-08-26 11:57