2012-06-28 56 views
6

上下文如何在瀏覽器

  • 我們有一個基於Ember公司,應用程序,它處理大量的結構化數據(業務流程模型)的處理顯示的數據的重載處理。
  • 重要!我們真的很想讓我們的應用程序儘可能地離線。

需要

雖然我們只需要顯示這些數據,對其進行編輯,等等,也沒有表明,塞在雷達...

但是現在,我們想要對這些模型應用處理:有效性檢查,路徑查找...和幾種時間/內存消耗算法。

問題

我們可以處理在服務器上的算法,但是這將終止該應用的離線模式。

我們已經考慮過網絡工作者避免在後臺凍結應用程序和過程算法,但我們遇到了一個主要問題:將數據傳遞給工作人員時出現數據重複。 使用Transferable對象會使應用程序在至少計算期間失去所有權(和數據),因此看起來不可行。

你將如何處理這個問題?我們唯一的出路是如何使用我們算法的「協同式」實現?任何線索?

+0

我認爲重要的問題是您是否可以承受不凍結的應用程序。假設用戶在算法運行時對數據進行更改。在後臺運行的進程結果是否仍然有效/相關?如果沒有,最好向用戶顯示進度條並繼續進行計算。 – Qnan

+0

數據重複有什麼問題?太多的東西序列化到工人? –

+0

@SimoneGianni主要問題是UI上下文和工作環境之間的數據同步 –

回答

3

如果您的主要擔心是在您開發的漫長JavaScript處理過程中不凍結UI,則可以將循環體重構爲連續步驟,以便每個步驟使用window.setTimeout調用其下一步。這種技術允許(單個)線程來處理每個交互之間的UI的事件:

var pr = function(x) {console.log(x)}; 
var COUNT=3; 

// original regular javascript loop 
for(var i=0; i<COUNT; i++) { 
    var msg = "current index is (" + i + ")"; 
    pr(msg); 
} 

// step-by-step sequential calls 
var body = function(i) { 
    var msg = "non-blocking for: index is (" + i + ")"; 
    pr(msg); 
} 
nonBlockingFor(body, 4); 

nonBlockingFor調用的第一個參數(作爲函數)的倍第二參數傳遞的數目的函數。它的定義如下:

// function constructor 
var nonBlockingFor = (function() { 
    function _run(context) { 
    if(context.idx > context.max) return; 
    context.fnc(context.idx++); 
    window.setTimeout((function(){ _run(context)}), 1); 
    } 
    return (function _start(ufn, uqt, runId) { 
    _run({idx: 0, max: uqt -1, fnc: ufn || (function(){}), runId: runId}); 
    }); 
})(); 

請注意,這是一個非常簡單的功能,它可以提高處理等多線程相關的問題 - 即:等待線程完成(加入)。我希望這段代碼能幫助你。請讓我知道,如果您喜歡這種解決方法,如果您願意,我可以花一些時間改進我的建議。

+0

非常感謝這個答案。實際上,這與我所說的「類協同程序」方法非常接近......這種解決方案的問題是,當算法趨於複雜時,整體實施複雜性呈爆炸式增長。 :-( –

+1

好的部分是,在你設置庫運行非阻塞/併發javascript後,你可以用一種前向齊次的方式開發商業庫。順便說一下,也許你已經知道了,但是這個庫似乎是一個很好的候選人[https://github.com/caolan/async/]。 –

+0

感謝您的鏈接。我不知道這個庫。聽起來很有趣。 –

2

很長一段時間已經過去了,但還是:一個解決方案可能是http://jscex.info/

JavaScript是單線程的本質上,這是一個設計選擇的原因多線程是一個很難的話題休閒的JavaScript開發者99%的人會不會妥善處理。

工作人員是獲得另一個線程並且不阻止UI的唯一方式,但爲了使它們在沒有真正多線程的危險副作用的情況下可用,它們在完全分離的上下文中運行,正如您注意到的那樣。所以它們更類似於調用傳遞命令行參數的外部命令而不是產生另一個線程。

因此,在「異步」模式下工作是目前唯一的解決方案,但由於您不需要等待點擊按鈕或遠程連接來完成,唯一可以綁定的異步事件是一個定時器,導致窮人的代碼風格困擾長期在js運行的操作。

然而,有一個小型圖書館,我發現它非常有趣,而且還很陌生,(儘管它的網站很差)能夠實時將一個精美的程序代碼「轉換」爲定時器和函數的混亂異步模式固有地要求:http://jscex.info/

正如在Windows 3.1中,您只需要「yield」($ await(Jscex.Async.sleep(50));)一段時間到瀏覽器,以便它不會完全凍結。它實際上會在引擎蓋下凍結,但是如果你足夠頻繁地產生,沒有人會注意到:)(最後,這就是多任務仍然可以在你的cpu的每個單核中運行,非常小的時間段,在此期間CPU是100%在一組指令上工作..把它拿到20毫秒,沒有人可以告訴)。

我認爲這可以幫助您「生成」一個類似於協程的JS,而不用實際「編寫」這樣的代碼,而是委託給一個「預編譯器」來完成它的工作。