2017-07-10 32 views
0

我正在嘗試使用閉包來加速我在Google腳本中的腳本代碼。這個概念對我來說是新的,但我想知道是否在下面的代碼中正確應用了閉包。 (代碼有效)這封閉是否正確,我的推理中是否存在任何錯誤

背景:代碼是計算一個月的百分比進展情況。

我不希望現在和月份的變量在每次調用該函數時都會更新,但只有在文檔打開後纔會更新。我基本上想要的是所有變量都只設置一次,如果函數被多次調用,該函數將提供一個答案。

這是一個很好的理由使用閉包,我是否正確使用它?

感謝您的建議和耐心。

// calculate progress with second precision 
var progressCalc = (function() { 

    const stMonth = SpreadsheetApp.getActive() 
    .getRangeByName("pStartdate") 
    .getValue(); 

    const eoMonth = SpreadsheetApp.getActive() 
    .getRangeByName("pEndOfMonthDate") 
    .getValue(); 

    const now = new Date(); 

    var unixProgressEoMonth = unixTime(eoMonth)-unixTime(stMonth) 
    var unixProgressNow = unixTime(now)-unixTime(stMonth) 

    return function() { return unixProgressNow/unixProgressEoMonth;}; 

})(); 

function progress() { 
    Logger.log(progressCalc()); 
    return progressCalc(); 
} 
+0

「*我正在嘗試使用閉包來加速我的腳本代碼*」 - 咦?請注意,您的返回函數(閉包)將始終返回相同的值,因此執行多次或重複除法沒有意義。你可以將結果值本身存儲在一個全局'progressVal'變量中,不需要'progressCalc'。 – Bergi

+0

我不知道我明白你的意思。你能舉一個快速的例子,我可以看看它嗎? – Christoph

+0

如果您能夠告訴/顯示我們在哪裏(多頻繁)調用「進度」或「progressCalc」,並且您的原始代碼沒有關閉看起來像是這樣,以便我們可以判斷加速和您是否應用了模式正確。 – Bergi

回答

1

我試圖用封閉工作,加快在谷歌腳本我的腳本代碼。

然後,您不應該每次調用progressCalc時都要評估計算。

這是使用閉包的好理由嗎?

不,實際上,你的計算結果是一個不變的結果,所以將它放入一個函數並根據它執行多次是沒有意義的。而不是存儲一個函數,只是馬上存儲結果值:

var progressValue = (function() { 

    const stMonth = SpreadsheetApp.getActive() 
    .getRangeByName("pStartdate") 
    .getValue(); 

    const eoMonth = SpreadsheetApp.getActive() 
    .getRangeByName("pEndOfMonthDate") 
    .getValue(); 

    const now = new Date(); 

    var unixProgressEoMonth = unixTime(eoMonth)-unixTime(stMonth) 
    var unixProgressNow = unixTime(now)-unixTime(stMonth) 

    return unixProgressNow/unixProgressEoMonth; 
})(); 

function progress() { 
    Logger.log(progressValue); 
} 
+0

好的最後一個問題:如果我理解正確,()將執行該功能。所以創建變量progressValue。插入無名(?)函數,通過在它後面放置()來在變量內執行它。接下來我可以使用progressValue而不用評估它,如果我不把它放在它後面。 – Christoph

+0

@Christoph [This pattern](https://stackoverflow.com/questions/26092101/what-is-this-javascript-pattern-called-and-why-is-it-it-used)被稱爲IIFE。不,無名的功能不是「插入」任何地方,只是創建,執行和遺忘。它甚至不知道變量。分配給變量的是* call的*返回值* - 在我們的例子中是一個數字 - 這就是爲什麼我們在使用它時不會把它放在後面的原因。 – Bergi

+0

感謝您的幫助!這很明顯。 – Christoph