我在舊的 aspx 網頁上的 JS 檔案中有一個簡單的 for 回圈:
function SaveCurrentFilterDisplay() {
var currentFilterCode = document.getElementById('curfilt').value;
var currentFilterList, currentFilterDisplay;
var i, str;
if (currentFilterCode != '') {
currentFilterList = document.getElementById(currentFilterCode);
currentFilterDisplay = document.getElementById(currentFilterCode '_display');
//save the previous filter text names
//alert(currentFilterCode ': ' currentFilterList.length);
if (currentFilterList.length) {
//multi-select list
str = '';
for (i = 0; i < currentFilterList.length; i ) {
if (currentFilterList.options[i].selected) {
if (str.length > 0) {
str = str ', '
}
str = str currentFilterList.options[i].text;
}
}
} else {
//text field
str = currentFilterList.value;
}
alert('finished looping');
currentFilterDisplay.value = str;
}
return true;
}
有時這個回圈必須回圈近 50,000 次。其他的只有幾百或更少。
令我困惑的是,當回圈必須回圈 50,000 次并且我在 Chrome 中運行它時,大約需要 2 分鐘。但是當我在 IE 中做同樣的事情時,它只需要幾秒鐘,有時它甚至看起來是瞬間的。
我想知道是否有與基于 Chrome 的瀏覽器如何處理 Javascript 有關的解釋?
編輯:也許關于如何優化它以便在 Chrome 中不需要 2 分鐘的任何建議?
編輯 2:我更新了我的問題以顯示整個功能。當我使用 Chrome 開發工具單步執行該函式時,該方法中的所有陳述句都會立即執行,但是當我單步執行回圈時,需要 2 分鐘才能觸發警報陳述句,因此回圈需要 2 分鐘。
下面是一些 HTML,顯示了 currentFilterList 指向的內容:
<select id="ID" name="adv" multiple="true">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
例如,currentFilterCode = "ID"。這使得 currentFilterList 設定為上面的選擇串列(由于明顯的原因,比真實的要短得多)。
最終編輯:在評論的幫助下,我確實發布了我所面臨的特定問題的解決方案。這不是解決類似情況的最佳方法,但它在我正在處理的應用程式的限制下作業。我選擇另一個答案作為解決方案,因為它是解決類似情況的方法。
uj5u.com熱心網友回復:
那么,當我們可以使用選擇器進行查找時,為什么還要回圈查找選擇呢?使用 map 和 join 建立一個選定值的字串。
document.querySelector("#select1").addEventListener("change", () => {
const out = [...document.querySelectorAll('#select1 option:checked')].map(x => x.text);
console.log(out.join(', '));
});
/*
document.querySelector("#select1").addEventListener("change", function() {
var out = Array.from(document.querySelectorAll('#select1 option:checked')).map(function(x) { return x.text; });
console.log(out.join(', '));
});
*/
<select id="select1" multiple>
<option>FOO1</option>
<option>FOO2</option>
<option>FOO3</option>
<option>FOO4</option>
<option>FOO5</option>
<option>FOO6</option>
<option>FOO7</option>
<option>FOO8</option>
<option>FOO9</option>
<option>FOO10</option>
</select>
或選擇選項并映射并加入
document.querySelector("#select1").addEventListener("change", () => {
var out = [...document.querySelector('#select1').selectedOptions].map(x => x.text);
console.log(out.join(', '));
});
<select id="select1" multiple>
<option>FOO1</option>
<option>FOO2</option>
<option>FOO3</option>
<option>FOO4</option>
<option>FOO5</option>
<option>FOO6</option>
<option>FOO7</option>
<option>FOO8</option>
<option>FOO9</option>
<option>FOO10</option>
</select>
uj5u.com熱心網友回復:
首先,當我試圖解決我在試圖優化時遇到的丑陋遺留代碼時,請在評論中向所有與我一起作業的人大喊大叫。多虧了他們,我才找到了解決方案。
問題與從回圈中的巨型選擇中的第 i個選項獲取屬性有關。
我發現這篇優秀的文章:https ://idiallo.com/javascript/minimize-lookups-in-for-loops
其中提到了幾種優化回圈訪問 DOM 元素的方法,就像我正在使用的那樣。作者提到創建和重新分配變數如何減慢它的速度(閱讀真實的東西,我不公正)。修復是在回圈之外創建變數并使用它們。應用更改后,我得到以下資訊:
function SaveCurrentFilterDisplay() {
var currentFilterCode = document.getElementById('curfilt').value;
var currentFilterList, currentFilterDisplay;
var i = 0, str, numOptions, selectedOptions;
if (currentFilterCode != '') {
currentFilterList = document.getElementById(currentFilterCode);
currentFilterDisplay = document.getElementById(currentFilterCode '_display');
selectedOptions = currentFilterList.selectedOptions;
numOptions = selectedOptions.length;
if (selectedOptions.length) {
str = '';
for (; i < numOptions; i ) {
if (str.length > 0) {
str = str ', '
}
str = str selectedOptions[i].text;
}
} else {
str = currentFilterList.value;
}
currentFilterDisplay.value = str;
}
}
作者提到性能提升將是微不足道的。然而,就像每個閱讀這篇文章的人一樣,他可能沒有考慮回圈超過 50,000 個選項的長選擇串列!
現在,這在不到一秒鐘的時間內運行了 50,000 個專案!
編輯:編輯為使用評論中提到的 selectedOptions 。這就是我讓這個舊網頁正常作業的方式。顯然這不是最好的解決方案,但它在應用程式的其余部分對我施加的限制范圍內作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/419309.html
標籤:
