2014-03-05 58 views
0

我正在嘗試使用Almond.js和Require.js優化器來創建一個獨立的文件,該文件可以在不使用Require.js的情況下使用。我已經能夠成功編譯該文件,並且可以運行所有代碼,但是存在一個問題:代碼以錯誤的順序執行。Require.js(almond.js)計時關

比方說,我的主文件(一個是在傳遞給優化的include=選項)有以下幾點:

console.log('outside'); 
require(['someFile'], function(someModule) { 
    console.log('inside'); 
    window.foo = someModule.rightValue; 
}); 

,然後出來在我的HTML我有:

<script src="myCompiledFile.js"></script> 
<script> 
    console.log('out in the HTML'); 
</script> 

由於我正在使用almond.js和一個編譯文件(因此沒有文件加載進行)我期望得到輸出:

outside 
inside 
out in the HTML 

然而,事實證明還是有一些異步回事,因爲我實際上看到的是:

outside 
out in the HTML 
inside 

,如果我嘗試從HTML檢查window.foo它不存在。

所以,我的問題是,我怎樣才能讓代碼更像是一個正常/同步的JS文件,在將代碼傳遞到下一個script塊之前先運行其所有代碼?我不能完全告訴我的用戶「將所有代碼包裝在window.setTimeout中」。

回答

2

默認情況下,杏仁複製RequireJS'require調用的時序語義。由於require在RequireJS中是異步的,因此它在Almond中也是異步的。在source中可以很容易地觀察到這一點:Almond使用setTimeout來安排模塊的執行,儘管它可以可以立即執行。這很有道理,因爲在通用情況下,開發人員不希望他們製作的異步工作代碼會因爲使用Almond而突然變得同步。在每個項目中都沒有關係,但在UI(例如)應該以特定順序刷新的項目中,更改定時語義可能會破壞代碼。

兩個選項:

  • 由於剛剛setTimeout狀態之前的評論,使用require('id')作品全球杏仁。這是因爲一旦你的bundle被加載,所有的東西都保證被加載(因爲Almond不會動態加載)。

  • 還有一種方法可以撥打requireextra arguments。如果第四個參數是真實的,呼叫將是同步的:

    require(['someFile'], function(someModule) { 
        console.log('inside'); 
        window.foo = someModule.rightValue; 
    }, undefined, true); 
    

這可以通過閱讀杏仁的代碼來確定。在forceSync(這是所討論的參數的名稱)上沒有找到任何文檔,但是有一些錯誤報告mention it,我還沒有看到任何評論意味着它是一個私有功能。

+0

感謝所有那些偉大的信息,但它並沒有真正解決我的問題。使用Require.js構建一個可共享庫是否真的不可能?我真的不想問問每個使用庫的人都需要'require('myLibrary')',我希望他們能夠引用一個全局變量(就像JQuery,Backbone,Underscore,Require本身一樣)。 )。 – machineghost

+0

你在評論中提出的問題不僅僅是你在問題中提出的問題。無論如何,它[這裏回答](https://github.com/jrburke/almond#exporting-a-public-api)。您會注意到,結尾片段使用我在答案中提到的require('id')'方法作爲可能的解決方案。 – Louis

+0

啊,我想我需要同步才能實現出口,但是你提供的鏈接看起來就像是一個完美的解決方案。謝謝。 – machineghost