2017-02-04 26 views
0

有幾種方法可以在JavaScript中創建和導入模塊,但據我所知它們都是爲了同步加載而設計的。如何創建並依賴異步JavaScript模塊?

爲了證明我所面臨的問題,我創建了這兩個例子CommonJS的模塊:

var Dependency; 
(function (Dependency) { 

    Dependency.data = 'Not loaded!'; 

    function doSomethingAsync() { 
     // Fetching data from server... 
     setTimeout(function() { 
      Dependency.data = 'Loaded!'; 
     }, 2000); 
    } 

})(Dependency = exports.Dependency || (exports.Dependency = {})); 

該模塊包含了一些異步代碼,並不能(/不應該)被同時「加載」使用。當試圖從另一個模塊使用data,它不會工作:

var dep = require("./dependency"); 
var MyModule; 
(function (MyModule) { 

    function useDependency() { 
     // Logs out 'Not loaded!' 
     console.log(dep.Dependency.data); 
    } 

    MyModule.useDependency = useDependency; 

})(MyModule = exports.MyModule || (exports.MyModule = {})); 

調用MyModule.useDependency()將顯示該Dependency無法使用呢。

我正在尋找一種方法來實現這個在我的項目中使用的通用結構。


我提出的解決方案是使用(ES6)承諾。我給每個模塊一個load()函數,這都返回一個承諾。所以在這種情況下,我會從某種入口文件調用Dependency.load().then(MyModule.load)。這在這種情況下可以正常工作,因爲useDependency()現在會打印出Loaded!。雖然我不確定這是否是最好的解決方案,因爲我需要手動跟蹤所有這些依賴關係。


所以我的問題是:什麼是處理這種異步模塊依賴關係的最佳途徑?是否有任何標準化的方式來做到這一點?

+0

'創建這樣一個異步模塊依賴樹的最佳方式是什麼? - 您發佈了一個「樹枝」並希望獲得「樹」的幫助 - 最好的解決方案是適用於您的項目總體設計,我猜 –

回答

1

我正在尋找一種方法來實現這個在我的項目中使用的通用結構。

由於您使用的是Common.js模塊,因此最好也是最簡單的方法是使每個導出(使用異步初始化的模塊)自己承諾。

(當然,如果是隻有一個模塊中的功能,那麼只有函數返回一個承諾)

// dependency.js 
var promise = new Promise(resolve => { 
    // Fetching data from server... 
    setTimeout(function() { 
     resolve('Loaded!') 
    }, 2000); 
}); 
module.exports = promise.then(data => { 
    … 
    return { 
     data, 
     … 
    }; 
}); 

// mymodule.js 
module.exports = Promise.all([ 
    require("./dependency"), 
    … 
]).then(([dep, …]) => { 
    … 
    return { 
     useDependency() { 
      console.log(dep.data); // 'Loaded' 
     }, 
     … 
    }; 
}); 

// main.js 
require('mymodule').then(MyModule => { 
    MyModule.useDependency(); 
}); 

注意這不適用於循環依賴。

對於ES6模塊,這個建議是完全無效的,ES6模塊目前不具有全局異步。